mirror of
https://github.com/git/git.git
synced 2024-11-28 12:34:08 +08:00
Merge branch 'master' of github.com:git/git
* 'master' of github.com:git/git: (34 commits) Git 2.42-rc2 t4053: avoid writing to unopened pipe t4053: avoid race when killing background processes Git 2.42-rc1 git maintenance: avoid console window in scheduled tasks on Windows win32: add a helper to run `git.exe` without a foreground window t9001: remove excessive GIT_SEND_EMAIL_NOTTY=1 mv: handle lstat() failure correctly parse-options: disallow negating OPTION_SET_INT 0 repack: free geometry struct send-email: avoid creating more than one Term::ReadLine object send-email: drop FakeTerm hack t0040: declare non-tab indentation to be okay in this script advice: handle "rebase" in error_resolve_conflict() A few more topics before -rc1 mailmap: change primary address for Glen Choo gitignore: ignore clangd .cache directory docs: update when `git bisect visualize` uses `gitk` compat/mingw: implement a native locate_in_PATH() run-command: conditionally define locate_in_PATH() ...
This commit is contained in:
commit
62a26b36bd
1
.gitignore
vendored
1
.gitignore
vendored
@ -222,6 +222,7 @@
|
||||
/TAGS
|
||||
/cscope*
|
||||
/compile_commands.json
|
||||
/.cache/
|
||||
*.hcc
|
||||
*.obj
|
||||
*.lib
|
||||
|
1
.mailmap
1
.mailmap
@ -80,6 +80,7 @@ Frank Lichtenheld <frank@lichtenheld.de> <flichtenheld@astaro.com>
|
||||
Fredrik Kuivinen <frekui@gmail.com> <freku045@student.liu.se>
|
||||
Frédéric Heitzmann <frederic.heitzmann@gmail.com>
|
||||
Garry Dolley <gdolley@ucla.edu> <gdolley@arpnetworks.com>
|
||||
Glen Choo <glencbz@gmail.com> <chooglen@google.com>
|
||||
Greg Price <price@mit.edu> <price@MIT.EDU>
|
||||
Greg Price <price@mit.edu> <price@ksplice.com>
|
||||
Heiko Voigt <hvoigt@hvoigt.net> <git-list@hvoigt.net>
|
||||
|
@ -38,6 +38,12 @@ UI, Workflows & Features
|
||||
being bisected or rebased. The message was reworded to say the
|
||||
branch was "in use".
|
||||
|
||||
* Tone down the warning on SHA-256 repositories being an experimental
|
||||
curiosity. We do not have support for them to interoperate with
|
||||
traditional SHA-1 repositories, but at this point, we do not plan
|
||||
to make breaking changes to SHA-256 repositories and there is no
|
||||
longer need for such a strongly phrased warning.
|
||||
|
||||
|
||||
Performance, Internal Implementation, Development Support etc.
|
||||
|
||||
@ -252,6 +258,36 @@ Fixes since v2.41
|
||||
submodule.<name>.update configuration variable.
|
||||
(merge 7cebc5bd78 pv/doc-submodule-update-settings later to maint).
|
||||
|
||||
* Adjust to OpenSSL 3+, which deprecates its SHA-1 functions based on
|
||||
its traditional API, by using its EVP API instead.
|
||||
(merge bda9c12073 ew/hash-with-openssl-evp later to maint).
|
||||
|
||||
* Exclude "." from the set of characters to be removed from the
|
||||
beginning and the end of the human-readable name.
|
||||
(merge 1c04cb0744 bc/ident-dot-is-no-longer-crud-letter later to maint).
|
||||
|
||||
* "git bisect visualize" stopped running "gitk" on Git for Windows
|
||||
when the command was reimplemented in C around Git 2.34 timeframe.
|
||||
This has been corrected.
|
||||
(merge fff1594fa7 ma/locate-in-path-for-windows later to maint).
|
||||
|
||||
* "git rebase -i" with a series of squash/fixup, when one of the
|
||||
steps stopped in conflicts and ended up getting skipped, did not
|
||||
handle the accumulated commit log messages, which has been
|
||||
corrected.
|
||||
(merge 6ce7afe163 pw/rebase-skip-commit-message-fix later to maint).
|
||||
|
||||
* Adjust to newer Term::ReadLine to prevent it from breaking
|
||||
the interactive prompt code in send-email.
|
||||
(merge c016726c2d jk/send-email-with-new-readline later to maint).
|
||||
|
||||
* Windows updates.
|
||||
(merge 0050f8e401 ds/maintenance-on-windows-fix later to maint).
|
||||
|
||||
* Correct use of lstat() that assumed a failing call would not
|
||||
clobber the statbuf.
|
||||
(merge 72695d8214 st/mv-lstat-fix later to maint).
|
||||
|
||||
* Other code cleanup, docfix, build fix, etc.
|
||||
(merge 51f9d2e563 sa/doc-ls-remote later to maint).
|
||||
(merge c6d26a9dda jk/format-patch-message-id-unleak later to maint).
|
||||
@ -286,3 +322,8 @@ Fixes since v2.41
|
||||
(merge c95ae3ff9c rs/describe-parseopt-fix later to maint).
|
||||
(merge 36f76d2a25 rs/pack-objects-parseopt-fix later to maint).
|
||||
(merge 30c8c55cbf jc/tree-walk-drop-base-offset later to maint).
|
||||
(merge d089a06421 rs/bundle-parseopt-cleanup later to maint).
|
||||
(merge 823839bda1 ew/sha256-gcrypt-leak-fixes later to maint).
|
||||
(merge a5c01603b3 bc/ignore-clangd-cache later to maint).
|
||||
(merge 12009a182b js/allow-t4000-to-be-indented-with-spaces later to maint).
|
||||
(merge b3dcd24b8a jc/send-email-pre-process-fix later to maint).
|
||||
|
@ -204,9 +204,14 @@ as an alternative to `visualize`):
|
||||
$ git bisect visualize
|
||||
------------
|
||||
|
||||
If the `DISPLAY` environment variable is not set, 'git log' is used
|
||||
instead. You can also give command-line options such as `-p` and
|
||||
`--stat`.
|
||||
Git detects a graphical environment through various environment variables:
|
||||
`DISPLAY`, which is set in X Window System environments on Unix systems.
|
||||
`SESSIONNAME`, which is set under Cygwin in interactive desktop sessions.
|
||||
`MSYSTEM`, which is set under Msys2 and Git for Windows.
|
||||
`SECURITYSESSIONID`, which may be set on macOS in interactive desktop sessions.
|
||||
|
||||
If none of these environment variables is set, 'git log' is used instead.
|
||||
You can also give command-line options such as `-p` and `--stat`.
|
||||
|
||||
------------
|
||||
$ git bisect visualize --stat
|
||||
|
@ -553,8 +553,8 @@ double-quotes and respecting backslash escapes. E.g., the value
|
||||
If this variable is set, the default hash algorithm for new
|
||||
repositories will be set to this value. This value is
|
||||
ignored when cloning and the setting of the remote repository
|
||||
is always used. The default is "sha1". THIS VARIABLE IS
|
||||
EXPERIMENTAL! See `--object-format` in linkgit:git-init[1].
|
||||
is always used. The default is "sha1".
|
||||
See `--object-format` in linkgit:git-init[1].
|
||||
|
||||
Git Commits
|
||||
~~~~~~~~~~~
|
||||
|
@ -1,6 +1,9 @@
|
||||
THIS OPTION IS EXPERIMENTAL! SHA-256 support is experimental and still
|
||||
in an early stage. A SHA-256 repository will in general not be able to
|
||||
share work with "regular" SHA-1 repositories. It should be assumed
|
||||
that, e.g., Git internal file formats in relation to SHA-256
|
||||
repositories may change in backwards-incompatible ways. Only use
|
||||
`--object-format=sha256` for testing purposes.
|
||||
Note: At present, there is no interoperability between SHA-256
|
||||
repositories and SHA-1 repositories.
|
||||
|
||||
Historically, we warned that SHA-256 repositories may later need
|
||||
backward incompatible changes when we introduce such interoperability
|
||||
features. Today, we only expect compatible changes. Furthermore, if such
|
||||
changes prove to be necessary, it can be expected that SHA-256 repositories
|
||||
created with today's Git will be usable by future versions of Git
|
||||
without data loss.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v2.42.0-rc0
|
||||
DEF_VER=v2.42.0-rc2
|
||||
|
||||
LF='
|
||||
'
|
||||
|
15
Makefile
15
Makefile
@ -2779,6 +2779,13 @@ compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
|
||||
compat/nedmalloc/nedmalloc.sp: SP_EXTRA_FLAGS += -Wno-non-pointer-null
|
||||
endif
|
||||
|
||||
headless-git.o: compat/win32/headless.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) $(ALL_CFLAGS) $(COMPAT_CFLAGS) \
|
||||
-fno-stack-protector -o $@ -c -Wall -Wwrite-strings $<
|
||||
|
||||
headless-git$X: headless-git.o git.res GIT-LDFLAGS
|
||||
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -mwindows -o $@ $< git.res
|
||||
|
||||
git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
|
||||
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
|
||||
|
||||
@ -3216,6 +3223,12 @@ $(SP_OBJ): %.sp: %.c %.o
|
||||
sparse: $(SP_OBJ)
|
||||
|
||||
EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/%
|
||||
ifndef OPENSSL_SHA1
|
||||
EXCEPT_HDRS += sha1/openssl.h
|
||||
endif
|
||||
ifndef OPENSSL_SHA256
|
||||
EXCEPT_HDRS += sha256/openssl.h
|
||||
endif
|
||||
ifndef NETTLE_SHA256
|
||||
EXCEPT_HDRS += sha256/nettle.h
|
||||
endif
|
||||
@ -3652,6 +3665,7 @@ clean: profile-clean coverage-clean cocciclean
|
||||
$(RM) po/git.pot po/git-core.pot
|
||||
$(RM) git.res
|
||||
$(RM) $(OBJECTS)
|
||||
$(RM) headless-git.o
|
||||
$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
|
||||
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)
|
||||
$(RM) $(TEST_PROGRAMS)
|
||||
@ -3680,6 +3694,7 @@ endif
|
||||
$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS
|
||||
ifdef MSVC
|
||||
$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))
|
||||
$(RM) headless-git.o.pdb
|
||||
$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))
|
||||
$(RM) $(patsubst %.exe,%.iobj,$(OTHER_PROGRAMS))
|
||||
$(RM) $(patsubst %.exe,%.ipdb,$(OTHER_PROGRAMS))
|
||||
|
5
advice.c
5
advice.c
@ -191,9 +191,10 @@ int error_resolve_conflict(const char *me)
|
||||
error(_("Pulling is not possible because you have unmerged files."));
|
||||
else if (!strcmp(me, "revert"))
|
||||
error(_("Reverting is not possible because you have unmerged files."));
|
||||
else if (!strcmp(me, "rebase"))
|
||||
error(_("Rebasing is not possible because you have unmerged files."));
|
||||
else
|
||||
error(_("It is not possible to %s because you have unmerged files."),
|
||||
me);
|
||||
BUG("Unhandled conflict reason '%s'", me);
|
||||
|
||||
if (advice_enabled(ADVICE_RESOLVE_CONFLICT))
|
||||
/*
|
||||
|
@ -68,42 +68,36 @@ static int parse_options_cmd_bundle(int argc,
|
||||
}
|
||||
|
||||
static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
|
||||
int all_progress_implied = 1;
|
||||
int progress = isatty(STDERR_FILENO);
|
||||
struct strvec pack_opts;
|
||||
struct strvec pack_opts = STRVEC_INIT;
|
||||
int version = -1;
|
||||
int ret;
|
||||
struct option options[] = {
|
||||
OPT_SET_INT('q', "quiet", &progress,
|
||||
N_("do not show progress meter"), 0),
|
||||
OPT_SET_INT(0, "progress", &progress,
|
||||
N_("show progress meter"), 1),
|
||||
OPT_SET_INT_F(0, "all-progress", &progress,
|
||||
N_("historical; same as --progress"), 2,
|
||||
PARSE_OPT_HIDDEN),
|
||||
OPT_HIDDEN_BOOL(0, "all-progress-implied",
|
||||
&all_progress_implied,
|
||||
N_("historical; does nothing")),
|
||||
OPT_PASSTHRU_ARGV('q', "quiet", &pack_opts, NULL,
|
||||
N_("do not show progress meter"),
|
||||
PARSE_OPT_NOARG),
|
||||
OPT_PASSTHRU_ARGV(0, "progress", &pack_opts, NULL,
|
||||
N_("show progress meter"),
|
||||
PARSE_OPT_NOARG),
|
||||
OPT_PASSTHRU_ARGV(0, "all-progress", &pack_opts, NULL,
|
||||
N_("historical; same as --progress"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),
|
||||
OPT_PASSTHRU_ARGV(0, "all-progress-implied", &pack_opts, NULL,
|
||||
N_("historical; does nothing"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),
|
||||
OPT_INTEGER(0, "version", &version,
|
||||
N_("specify bundle format version")),
|
||||
OPT_END()
|
||||
};
|
||||
char *bundle_file;
|
||||
|
||||
if (isatty(STDERR_FILENO))
|
||||
strvec_push(&pack_opts, "--progress");
|
||||
strvec_push(&pack_opts, "--all-progress-implied");
|
||||
|
||||
argc = parse_options_cmd_bundle(argc, argv, prefix,
|
||||
builtin_bundle_create_usage, options, &bundle_file);
|
||||
/* bundle internals use argv[1] as further parameters */
|
||||
|
||||
strvec_init(&pack_opts);
|
||||
if (progress == 0)
|
||||
strvec_push(&pack_opts, "--quiet");
|
||||
else if (progress == 1)
|
||||
strvec_push(&pack_opts, "--progress");
|
||||
else if (progress == 2)
|
||||
strvec_push(&pack_opts, "--all-progress");
|
||||
if (progress && all_progress_implied)
|
||||
strvec_push(&pack_opts, "--all-progress-implied");
|
||||
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to create a bundle."));
|
||||
ret = !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
|
||||
|
@ -2068,7 +2068,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
|
||||
"</Settings>\n"
|
||||
"<Actions Context=\"Author\">\n"
|
||||
"<Exec>\n"
|
||||
"<Command>\"%s\\git.exe\"</Command>\n"
|
||||
"<Command>\"%s\\headless-git.exe\"</Command>\n"
|
||||
"<Arguments>--exec-path=\"%s\" for-each-repo --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
|
||||
"</Exec>\n"
|
||||
"</Actions>\n"
|
||||
|
@ -184,7 +184,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
int src_dir_nr = 0, src_dir_alloc = 0;
|
||||
struct strbuf a_src_dir = STRBUF_INIT;
|
||||
enum update_mode *modes, dst_mode = 0;
|
||||
struct stat st;
|
||||
struct stat st, dest_st;
|
||||
struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
|
||||
struct lock_file lock_file = LOCK_INIT;
|
||||
struct cache_entry *ce;
|
||||
@ -304,7 +304,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
goto act_on_entry;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)
|
||||
&& lstat(dst, &st) == 0) {
|
||||
&& lstat(dst, &dest_st) == 0) {
|
||||
bad = _("cannot move directory over file");
|
||||
goto act_on_entry;
|
||||
}
|
||||
|
@ -492,15 +492,13 @@ static struct packed_git *get_preferred_pack(struct pack_geometry *geometry)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void clear_pack_geometry(struct pack_geometry *geometry)
|
||||
static void free_pack_geometry(struct pack_geometry *geometry)
|
||||
{
|
||||
if (!geometry)
|
||||
return;
|
||||
|
||||
free(geometry->pack);
|
||||
geometry->pack_nr = 0;
|
||||
geometry->pack_alloc = 0;
|
||||
geometry->split = 0;
|
||||
free(geometry);
|
||||
}
|
||||
|
||||
struct midx_snapshot_ref_data {
|
||||
@ -1228,7 +1226,7 @@ cleanup:
|
||||
string_list_clear(&names, 1);
|
||||
string_list_clear(&existing_nonkept_packs, 0);
|
||||
string_list_clear(&existing_kept_packs, 0);
|
||||
clear_pack_geometry(geometry);
|
||||
free_pack_geometry(geometry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1347,6 +1347,11 @@ static char *path_lookup(const char *cmd, int exe_only)
|
||||
return prog;
|
||||
}
|
||||
|
||||
char *mingw_locate_in_PATH(const char *cmd)
|
||||
{
|
||||
return path_lookup(cmd, 0);
|
||||
}
|
||||
|
||||
static const wchar_t *wcschrnul(const wchar_t *s, wchar_t c)
|
||||
{
|
||||
while (*s && *s != c)
|
||||
|
@ -177,6 +177,9 @@ pid_t waitpid(pid_t pid, int *status, int options);
|
||||
#define kill mingw_kill
|
||||
int mingw_kill(pid_t pid, int sig);
|
||||
|
||||
#define locate_in_PATH mingw_locate_in_PATH
|
||||
char *mingw_locate_in_PATH(const char *cmd);
|
||||
|
||||
#ifndef NO_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
static inline int mingw_SSL_set_fd(SSL *ssl, int fd)
|
||||
|
115
compat/win32/headless.c
Normal file
115
compat/win32/headless.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* headless Git - run Git without opening a console window on Windows
|
||||
*/
|
||||
|
||||
#define STRICT
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
* If `dir` contains the path to a Git exec directory, extend `PATH` to
|
||||
* include the corresponding `bin/` directory (which is where all those
|
||||
* `.dll` files needed by `git.exe` are, on Windows).
|
||||
*/
|
||||
static int extend_path(wchar_t *dir, size_t dir_len)
|
||||
{
|
||||
const wchar_t *suffix = L"\\libexec\\git-core";
|
||||
size_t suffix_len = wcslen(suffix);
|
||||
wchar_t *env;
|
||||
DWORD len;
|
||||
|
||||
if (dir_len < suffix_len)
|
||||
return 0;
|
||||
|
||||
dir_len -= suffix_len;
|
||||
if (memcmp(dir + dir_len, suffix, suffix_len * sizeof(wchar_t)))
|
||||
return 0;
|
||||
|
||||
len = GetEnvironmentVariableW(L"PATH", NULL, 0);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
env = _alloca((dir_len + 5 + len) * sizeof(wchar_t));
|
||||
wcsncpy(env, dir, dir_len);
|
||||
wcscpy(env + dir_len, L"\\bin;");
|
||||
if (!GetEnvironmentVariableW(L"PATH", env + dir_len + 5, len))
|
||||
return 0;
|
||||
|
||||
SetEnvironmentVariableW(L"PATH", env);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(_In_ HINSTANCE instance,
|
||||
_In_opt_ HINSTANCE previous_instance,
|
||||
_In_ LPWSTR command_line, _In_ int show)
|
||||
{
|
||||
wchar_t git_command_line[32768];
|
||||
size_t size = sizeof(git_command_line) / sizeof(wchar_t);
|
||||
const wchar_t *needs_quotes = L"";
|
||||
int slash = 0, i;
|
||||
|
||||
STARTUPINFO startup_info = {
|
||||
.cb = sizeof(STARTUPINFO),
|
||||
.dwFlags = STARTF_USESHOWWINDOW,
|
||||
.wShowWindow = SW_HIDE,
|
||||
};
|
||||
PROCESS_INFORMATION process_info = { 0 };
|
||||
DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT |
|
||||
CREATE_NEW_CONSOLE | CREATE_NO_WINDOW;
|
||||
DWORD exit_code;
|
||||
|
||||
/* First, determine the full path of argv[0] */
|
||||
for (i = 0; _wpgmptr[i]; i++)
|
||||
if (_wpgmptr[i] == L' ')
|
||||
needs_quotes = L"\"";
|
||||
else if (_wpgmptr[i] == L'\\')
|
||||
slash = i;
|
||||
|
||||
if (slash >= size - 11)
|
||||
return 127; /* Too long path */
|
||||
|
||||
/* If it is in Git's exec path, add the bin/ directory to the PATH */
|
||||
extend_path(_wpgmptr, slash);
|
||||
|
||||
/* Then, add the full path of `git.exe` as argv[0] */
|
||||
i = swprintf_s(git_command_line, size, L"%ls%.*ls\\git.exe%ls",
|
||||
needs_quotes, slash, _wpgmptr, needs_quotes);
|
||||
if (i < 0)
|
||||
return 127; /* Too long path */
|
||||
|
||||
if (*command_line) {
|
||||
/* Now, append the command-line arguments */
|
||||
i = swprintf_s(git_command_line + i, size - i,
|
||||
L" %ls", command_line);
|
||||
if (i < 0)
|
||||
return 127;
|
||||
}
|
||||
|
||||
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
if (!CreateProcess(NULL, /* infer argv[0] from the command line */
|
||||
git_command_line, /* modified command line */
|
||||
NULL, /* inherit process handles? */
|
||||
NULL, /* inherit thread handles? */
|
||||
FALSE, /* handles inheritable? */
|
||||
creation_flags,
|
||||
NULL, /* use this process' environment */
|
||||
NULL, /* use this process' working directory */
|
||||
&startup_info, &process_info))
|
||||
return 129; /* could not start */
|
||||
WaitForSingleObject(process_info.hProcess, INFINITE);
|
||||
if (!GetExitCodeProcess(process_info.hProcess, &exit_code))
|
||||
exit_code = 130; /* Could not determine exit code? */
|
||||
|
||||
CloseHandle(process_info.hProcess);
|
||||
CloseHandle(process_info.hThread);
|
||||
|
||||
return (int)exit_code;
|
||||
}
|
@ -526,6 +526,8 @@ else
|
||||
endif
|
||||
X = .exe
|
||||
|
||||
EXTRA_PROGRAMS += headless-git$X
|
||||
|
||||
compat/msvc.o: compat/msvc.c compat/mingw.c GIT-CFLAGS
|
||||
endif
|
||||
ifeq ($(uname_S),Interix)
|
||||
@ -705,6 +707,7 @@ ifeq ($(uname_S),MINGW)
|
||||
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY \
|
||||
-fstack-protector-strong
|
||||
EXTLIBS += -lntdll
|
||||
EXTRA_PROGRAMS += headless-git$X
|
||||
INSTALL = /bin/install
|
||||
INTERNAL_QSORT = YesPlease
|
||||
HAVE_LIBCHARSET_H = YesPlease
|
||||
|
@ -738,6 +738,15 @@ if(WIN32)
|
||||
else()
|
||||
message(FATAL_ERROR "Unhandled compiler: ${CMAKE_C_COMPILER_ID}")
|
||||
endif()
|
||||
|
||||
add_executable(headless-git ${CMAKE_SOURCE_DIR}/compat/win32/headless.c)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
target_link_options(headless-git PUBLIC -municode -Wl,-subsystem,windows)
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
target_link_options(headless-git PUBLIC /NOLOGO /ENTRY:wWinMainCRTStartup /SUBSYSTEM:WINDOWS)
|
||||
else()
|
||||
message(FATAL_ERROR "Unhandled compiler: ${CMAKE_C_COMPILER_ID}")
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
target_link_libraries(common-main pthread rt)
|
||||
endif()
|
||||
|
@ -76,7 +76,7 @@ sub createProject {
|
||||
|
||||
my $libs_release = "\n ";
|
||||
my $libs_debug = "\n ";
|
||||
if (!$static_library) {
|
||||
if (!$static_library && $name ne 'headless-git') {
|
||||
$libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
|
||||
$libs_debug = $libs_release;
|
||||
$libs_debug =~ s/zlib\.lib/zlibd\.lib/g;
|
||||
@ -230,7 +230,7 @@ EOM
|
||||
print F << "EOM";
|
||||
</ItemGroup>
|
||||
EOM
|
||||
if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
|
||||
if ((!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') && !($name =~ /headless-git/)) {
|
||||
my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
|
||||
my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"};
|
||||
my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
|
||||
|
@ -371,6 +371,7 @@ sub handleLinkLine
|
||||
# exit(1);
|
||||
foreach (@objfiles) {
|
||||
my $sourcefile = $_;
|
||||
$sourcefile =~ s/^headless-git\.o$/compat\/win32\/headless.c/;
|
||||
$sourcefile =~ s/\.o$/.c/;
|
||||
push(@sources, $sourcefile);
|
||||
push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
|
||||
|
@ -26,18 +26,6 @@ use Git::I18N;
|
||||
|
||||
Getopt::Long::Configure qw/ pass_through /;
|
||||
|
||||
package FakeTerm;
|
||||
sub new {
|
||||
my ($class, $reason) = @_;
|
||||
return bless \$reason, shift;
|
||||
}
|
||||
sub readline {
|
||||
my $self = shift;
|
||||
die "Cannot use readline on FakeTerm: $$self";
|
||||
}
|
||||
package main;
|
||||
|
||||
|
||||
sub usage {
|
||||
print <<EOT;
|
||||
git send-email' [<options>] <file|directory>
|
||||
@ -971,17 +959,19 @@ EOT3
|
||||
do_edit(@files);
|
||||
}
|
||||
|
||||
sub term {
|
||||
my $term = eval {
|
||||
{
|
||||
# Only instantiate one $term per program run, since some
|
||||
# Term::ReadLine providers refuse to create a second instance.
|
||||
my $term;
|
||||
sub term {
|
||||
require Term::ReadLine;
|
||||
$ENV{"GIT_SEND_EMAIL_NOTTY"}
|
||||
? Term::ReadLine->new('git-send-email', \*STDIN, \*STDOUT)
|
||||
: Term::ReadLine->new('git-send-email');
|
||||
};
|
||||
if ($@) {
|
||||
$term = FakeTerm->new("$@: going non-interactive");
|
||||
if (!defined $term) {
|
||||
$term = $ENV{"GIT_SEND_EMAIL_NOTTY"}
|
||||
? Term::ReadLine->new('git-send-email', \*STDIN, \*STDOUT)
|
||||
: Term::ReadLine->new('git-send-email');
|
||||
}
|
||||
return $term;
|
||||
}
|
||||
return $term;
|
||||
}
|
||||
|
||||
sub ask {
|
||||
|
18
hash-ll.h
18
hash-ll.h
@ -4,7 +4,11 @@
|
||||
#if defined(SHA1_APPLE)
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#elif defined(SHA1_OPENSSL)
|
||||
#include <openssl/sha.h>
|
||||
# include <openssl/sha.h>
|
||||
# if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
|
||||
# define SHA1_NEEDS_CLONE_HELPER
|
||||
# include "sha1/openssl.h"
|
||||
# endif
|
||||
#elif defined(SHA1_DC)
|
||||
#include "sha1dc_git.h"
|
||||
#else /* SHA1_BLK */
|
||||
@ -17,7 +21,11 @@
|
||||
#define SHA256_NEEDS_CLONE_HELPER
|
||||
#include "sha256/gcrypt.h"
|
||||
#elif defined(SHA256_OPENSSL)
|
||||
#include <openssl/sha.h>
|
||||
# include <openssl/sha.h>
|
||||
# if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
|
||||
# define SHA256_NEEDS_CLONE_HELPER
|
||||
# include "sha256/openssl.h"
|
||||
# endif
|
||||
#else
|
||||
#include "sha256/block/sha256.h"
|
||||
#endif
|
||||
@ -41,6 +49,10 @@
|
||||
#define git_SHA1_Update platform_SHA1_Update
|
||||
#define git_SHA1_Final platform_SHA1_Final
|
||||
|
||||
#ifdef platform_SHA1_Clone
|
||||
#define git_SHA1_Clone platform_SHA1_Clone
|
||||
#endif
|
||||
|
||||
#ifndef platform_SHA256_CTX
|
||||
#define platform_SHA256_CTX SHA256_CTX
|
||||
#define platform_SHA256_Init SHA256_Init
|
||||
@ -63,10 +75,12 @@
|
||||
#define git_SHA1_Update git_SHA1_Update_Chunked
|
||||
#endif
|
||||
|
||||
#ifndef SHA1_NEEDS_CLONE_HELPER
|
||||
static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
|
||||
{
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SHA256_NEEDS_CLONE_HELPER
|
||||
static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
|
||||
|
1
ident.c
1
ident.c
@ -203,7 +203,6 @@ void reset_ident_date(void)
|
||||
static int crud(unsigned char c)
|
||||
{
|
||||
return c <= 32 ||
|
||||
c == '.' ||
|
||||
c == ',' ||
|
||||
c == ':' ||
|
||||
c == ';' ||
|
||||
|
@ -480,6 +480,9 @@ static void parse_options_check(const struct option *opts)
|
||||
opts->long_name))
|
||||
optbug(opts, "uses feature "
|
||||
"not supported for dashless options");
|
||||
if (opts->type == OPTION_SET_INT && !opts->defval &&
|
||||
opts->long_name && !(opts->flags & PARSE_OPT_NONEG))
|
||||
optbug(opts, "OPTION_SET_INT 0 should not be negatable");
|
||||
switch (opts->type) {
|
||||
case OPTION_COUNTUP:
|
||||
case OPTION_BIT:
|
||||
|
@ -170,6 +170,7 @@ int is_executable(const char *name)
|
||||
return st.st_mode & S_IXUSR;
|
||||
}
|
||||
|
||||
#ifndef locate_in_PATH
|
||||
/*
|
||||
* Search $PATH for a command. This emulates the path search that
|
||||
* execvp would perform, without actually executing the command so it
|
||||
@ -218,6 +219,7 @@ static char *locate_in_PATH(const char *file)
|
||||
strbuf_release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int exists_in_PATH(const char *command)
|
||||
{
|
||||
|
28
sequencer.c
28
sequencer.c
@ -5048,19 +5048,31 @@ static int commit_staged_changes(struct repository *r,
|
||||
* We need to update the squash message to skip
|
||||
* the latest commit message.
|
||||
*/
|
||||
int res = 0;
|
||||
struct commit *commit;
|
||||
const char *msg;
|
||||
const char *path = rebase_path_squash_msg();
|
||||
const char *encoding = get_commit_output_encoding();
|
||||
|
||||
if (parse_head(r, &commit) ||
|
||||
!(p = repo_logmsg_reencode(r, commit, NULL, encoding)) ||
|
||||
write_message(p, strlen(p), path, 0)) {
|
||||
repo_unuse_commit_buffer(r, commit, p);
|
||||
return error(_("could not write file: "
|
||||
"'%s'"), path);
|
||||
if (parse_head(r, &commit))
|
||||
return error(_("could not parse HEAD"));
|
||||
|
||||
p = repo_logmsg_reencode(r, commit, NULL, encoding);
|
||||
if (!p) {
|
||||
res = error(_("could not parse commit %s"),
|
||||
oid_to_hex(&commit->object.oid));
|
||||
goto unuse_commit_buffer;
|
||||
}
|
||||
repo_unuse_commit_buffer(r,
|
||||
commit, p);
|
||||
find_commit_subject(p, &msg);
|
||||
if (write_message(msg, strlen(msg), path, 0)) {
|
||||
res = error(_("could not write file: "
|
||||
"'%s'"), path);
|
||||
goto unuse_commit_buffer;
|
||||
}
|
||||
unuse_commit_buffer:
|
||||
repo_unuse_commit_buffer(r, commit, p);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
49
sha1/openssl.h
Normal file
49
sha1/openssl.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* wrappers for the EVP API of OpenSSL 3+ */
|
||||
#ifndef SHA1_OPENSSL_H
|
||||
#define SHA1_OPENSSL_H
|
||||
#include <openssl/evp.h>
|
||||
|
||||
struct openssl_SHA1_CTX {
|
||||
EVP_MD_CTX *ectx;
|
||||
};
|
||||
|
||||
typedef struct openssl_SHA1_CTX openssl_SHA1_CTX;
|
||||
|
||||
static inline void openssl_SHA1_Init(struct openssl_SHA1_CTX *ctx)
|
||||
{
|
||||
const EVP_MD *type = EVP_sha1();
|
||||
|
||||
ctx->ectx = EVP_MD_CTX_new();
|
||||
if (!ctx->ectx)
|
||||
die("EVP_MD_CTX_new: out of memory");
|
||||
|
||||
EVP_DigestInit_ex(ctx->ectx, type, NULL);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA1_Update(struct openssl_SHA1_CTX *ctx,
|
||||
const void *data,
|
||||
size_t len)
|
||||
{
|
||||
EVP_DigestUpdate(ctx->ectx, data, len);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA1_Final(unsigned char *digest,
|
||||
struct openssl_SHA1_CTX *ctx)
|
||||
{
|
||||
EVP_DigestFinal_ex(ctx->ectx, digest, NULL);
|
||||
EVP_MD_CTX_free(ctx->ectx);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA1_Clone(struct openssl_SHA1_CTX *dst,
|
||||
const struct openssl_SHA1_CTX *src)
|
||||
{
|
||||
EVP_MD_CTX_copy_ex(dst->ectx, src->ectx);
|
||||
}
|
||||
|
||||
#define platform_SHA_CTX openssl_SHA1_CTX
|
||||
#define platform_SHA1_Init openssl_SHA1_Init
|
||||
#define platform_SHA1_Clone openssl_SHA1_Clone
|
||||
#define platform_SHA1_Update openssl_SHA1_Update
|
||||
#define platform_SHA1_Final openssl_SHA1_Final
|
||||
|
||||
#endif /* SHA1_OPENSSL_H */
|
@ -7,22 +7,25 @@
|
||||
|
||||
typedef gcry_md_hd_t gcrypt_SHA256_CTX;
|
||||
|
||||
inline void gcrypt_SHA256_Init(gcrypt_SHA256_CTX *ctx)
|
||||
static inline void gcrypt_SHA256_Init(gcrypt_SHA256_CTX *ctx)
|
||||
{
|
||||
gcry_md_open(ctx, GCRY_MD_SHA256, 0);
|
||||
gcry_error_t err = gcry_md_open(ctx, GCRY_MD_SHA256, 0);
|
||||
if (err)
|
||||
die("gcry_md_open: %s", gcry_strerror(err));
|
||||
}
|
||||
|
||||
inline void gcrypt_SHA256_Update(gcrypt_SHA256_CTX *ctx, const void *data, size_t len)
|
||||
static inline void gcrypt_SHA256_Update(gcrypt_SHA256_CTX *ctx, const void *data, size_t len)
|
||||
{
|
||||
gcry_md_write(*ctx, data, len);
|
||||
}
|
||||
|
||||
inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
|
||||
static inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
|
||||
{
|
||||
memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
|
||||
gcry_md_close(*ctx);
|
||||
}
|
||||
|
||||
inline void gcrypt_SHA256_Clone(gcrypt_SHA256_CTX *dst, const gcrypt_SHA256_CTX *src)
|
||||
static inline void gcrypt_SHA256_Clone(gcrypt_SHA256_CTX *dst, const gcrypt_SHA256_CTX *src)
|
||||
{
|
||||
gcry_md_copy(dst, *src);
|
||||
}
|
||||
|
49
sha256/openssl.h
Normal file
49
sha256/openssl.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* wrappers for the EVP API of OpenSSL 3+ */
|
||||
#ifndef SHA256_OPENSSL_H
|
||||
#define SHA256_OPENSSL_H
|
||||
#include <openssl/evp.h>
|
||||
|
||||
struct openssl_SHA256_CTX {
|
||||
EVP_MD_CTX *ectx;
|
||||
};
|
||||
|
||||
typedef struct openssl_SHA256_CTX openssl_SHA256_CTX;
|
||||
|
||||
static inline void openssl_SHA256_Init(struct openssl_SHA256_CTX *ctx)
|
||||
{
|
||||
const EVP_MD *type = EVP_sha256();
|
||||
|
||||
ctx->ectx = EVP_MD_CTX_new();
|
||||
if (!ctx->ectx)
|
||||
die("EVP_MD_CTX_new: out of memory");
|
||||
|
||||
EVP_DigestInit_ex(ctx->ectx, type, NULL);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA256_Update(struct openssl_SHA256_CTX *ctx,
|
||||
const void *data,
|
||||
size_t len)
|
||||
{
|
||||
EVP_DigestUpdate(ctx->ectx, data, len);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA256_Final(unsigned char *digest,
|
||||
struct openssl_SHA256_CTX *ctx)
|
||||
{
|
||||
EVP_DigestFinal_ex(ctx->ectx, digest, NULL);
|
||||
EVP_MD_CTX_free(ctx->ectx);
|
||||
}
|
||||
|
||||
static inline void openssl_SHA256_Clone(struct openssl_SHA256_CTX *dst,
|
||||
const struct openssl_SHA256_CTX *src)
|
||||
{
|
||||
EVP_MD_CTX_copy_ex(dst->ectx, src->ectx);
|
||||
}
|
||||
|
||||
#define platform_SHA256_CTX openssl_SHA256_CTX
|
||||
#define platform_SHA256_Init openssl_SHA256_Init
|
||||
#define platform_SHA256_Clone openssl_SHA256_Clone
|
||||
#define platform_SHA256_Update openssl_SHA256_Update
|
||||
#define platform_SHA256_Final openssl_SHA256_Final
|
||||
|
||||
#endif /* SHA256_OPENSSL_H */
|
1
t/.gitattributes
vendored
1
t/.gitattributes
vendored
@ -22,3 +22,4 @@ t[0-9][0-9][0-9][0-9]/* -whitespace
|
||||
/t7500/* eol=lf
|
||||
/t8005/*.txt eol=lf
|
||||
/t9*/*.dump eol=lf
|
||||
/t0040*.sh whitespace=-indent-with-non-tab
|
||||
|
@ -14,24 +14,37 @@ graph_git_two_modes() {
|
||||
test_cmp expect output
|
||||
}
|
||||
|
||||
# graph_git_behavior <name> <directory> <branch> <compare>
|
||||
#
|
||||
# Ensures that a handful of traversal operations produce the same
|
||||
# results with and without the commit-graph in use.
|
||||
#
|
||||
# NOTE: it is a bug to call this function with <directory> containing
|
||||
# any characters in $IFS.
|
||||
graph_git_behavior() {
|
||||
MSG=$1
|
||||
DIR=$2
|
||||
BRANCH=$3
|
||||
COMPARE=$4
|
||||
test_expect_success "check normal git operations: $MSG" '
|
||||
cd "$TRASH_DIRECTORY/$DIR" &&
|
||||
graph_git_two_modes "log --oneline $BRANCH" &&
|
||||
graph_git_two_modes "log --topo-order $BRANCH" &&
|
||||
graph_git_two_modes "log --graph $COMPARE..$BRANCH" &&
|
||||
graph_git_two_modes "branch -vv" &&
|
||||
graph_git_two_modes "merge-base -a $BRANCH $COMPARE"
|
||||
graph_git_two_modes "${DIR:+-C $DIR} log --oneline $BRANCH" &&
|
||||
graph_git_two_modes "${DIR:+-C $DIR} log --topo-order $BRANCH" &&
|
||||
graph_git_two_modes "${DIR:+-C $DIR} log --graph $COMPARE..$BRANCH" &&
|
||||
graph_git_two_modes "${DIR:+-C $DIR} branch -vv" &&
|
||||
graph_git_two_modes "${DIR:+-C $DIR} merge-base -a $BRANCH $COMPARE"
|
||||
'
|
||||
}
|
||||
|
||||
graph_read_expect() {
|
||||
OPTIONAL=""
|
||||
NUM_CHUNKS=3
|
||||
DIR="."
|
||||
if test "$1" = -C
|
||||
then
|
||||
shift
|
||||
DIR="$1"
|
||||
shift
|
||||
fi
|
||||
if test -n "$2"
|
||||
then
|
||||
OPTIONAL=" $2"
|
||||
@ -47,12 +60,15 @@ graph_read_expect() {
|
||||
then
|
||||
OPTIONS=" read_generation_data"
|
||||
fi
|
||||
cat >expect <<- EOF
|
||||
cat >"$DIR/expect" <<-EOF
|
||||
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
|
||||
num_commits: $1
|
||||
chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL
|
||||
options:$OPTIONS
|
||||
EOF
|
||||
test-tool read-graph >output &&
|
||||
test_cmp expect output
|
||||
(
|
||||
cd "$DIR" &&
|
||||
test-tool read-graph >output &&
|
||||
test_cmp expect output
|
||||
)
|
||||
}
|
||||
|
@ -115,15 +115,23 @@ test_expect_success '--skip after failed fixup cleans commit message' '
|
||||
test_when_finished "test_might_fail git rebase --abort" &&
|
||||
git checkout -b with-conflicting-fixup &&
|
||||
test_commit wants-fixup &&
|
||||
test_commit "fixup! wants-fixup" wants-fixup.t 1 wants-fixup-1 &&
|
||||
test_commit "fixup! wants-fixup" wants-fixup.t 2 wants-fixup-2 &&
|
||||
test_commit "fixup! wants-fixup" wants-fixup.t 3 wants-fixup-3 &&
|
||||
test_commit "fixup 1" wants-fixup.t 1 wants-fixup-1 &&
|
||||
test_commit "fixup 2" wants-fixup.t 2 wants-fixup-2 &&
|
||||
test_commit "fixup 3" wants-fixup.t 3 wants-fixup-3 &&
|
||||
test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
|
||||
git rebase -i HEAD~4 &&
|
||||
|
||||
: now there is a conflict, and comments in the commit message &&
|
||||
git show HEAD >out &&
|
||||
grep "fixup! wants-fixup" out &&
|
||||
test_commit_message HEAD <<-\EOF &&
|
||||
# This is a combination of 2 commits.
|
||||
# This is the 1st commit message:
|
||||
|
||||
wants-fixup
|
||||
|
||||
# The commit message #2 will be skipped:
|
||||
|
||||
# fixup 1
|
||||
EOF
|
||||
|
||||
: skip and continue &&
|
||||
echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh &&
|
||||
@ -133,33 +141,49 @@ test_expect_success '--skip after failed fixup cleans commit message' '
|
||||
test_path_is_missing .git/copy.txt &&
|
||||
|
||||
: now the comments in the commit message should have been cleaned up &&
|
||||
git show HEAD >out &&
|
||||
! grep "fixup! wants-fixup" out &&
|
||||
test_commit_message HEAD -m wants-fixup &&
|
||||
|
||||
: now, let us ensure that "squash" is handled correctly &&
|
||||
git reset --hard wants-fixup-3 &&
|
||||
test_must_fail env FAKE_LINES="1 squash 4 squash 2 squash 4" \
|
||||
test_must_fail env FAKE_LINES="1 squash 2 squash 1 squash 3 squash 1" \
|
||||
git rebase -i HEAD~4 &&
|
||||
|
||||
: the first squash failed, but there are two more in the chain &&
|
||||
: the second squash failed, but there are two more in the chain &&
|
||||
(test_set_editor "$PWD/copy-editor.sh" &&
|
||||
test_must_fail git rebase --skip) &&
|
||||
|
||||
: not the final squash, no need to edit the commit message &&
|
||||
test_path_is_missing .git/copy.txt &&
|
||||
|
||||
: The first squash was skipped, therefore: &&
|
||||
git show HEAD >out &&
|
||||
test_i18ngrep "# This is a combination of 2 commits" out &&
|
||||
test_i18ngrep "# This is the commit message #2:" out &&
|
||||
: The first and third squashes succeeded, therefore: &&
|
||||
test_commit_message HEAD <<-\EOF &&
|
||||
# This is a combination of 3 commits.
|
||||
# This is the 1st commit message:
|
||||
|
||||
wants-fixup
|
||||
|
||||
# This is the commit message #2:
|
||||
|
||||
fixup 1
|
||||
|
||||
# This is the commit message #3:
|
||||
|
||||
fixup 2
|
||||
EOF
|
||||
|
||||
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
|
||||
git show HEAD >out &&
|
||||
test_i18ngrep ! "# This is a combination" out &&
|
||||
test_commit_message HEAD <<-\EOF &&
|
||||
wants-fixup
|
||||
|
||||
fixup 1
|
||||
|
||||
fixup 2
|
||||
EOF
|
||||
|
||||
: Final squash failed, but there was still a squash &&
|
||||
test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt &&
|
||||
test_i18ngrep "# This is the commit message #2:" .git/copy.txt
|
||||
head -n1 .git/copy.txt >first-line &&
|
||||
test_i18ngrep "# This is a combination of 3 commits" first-line &&
|
||||
test_i18ngrep "# This is the commit message #3:" .git/copy.txt
|
||||
'
|
||||
|
||||
test_expect_success 'setup rerere database' '
|
||||
|
@ -21,21 +21,6 @@ TEST_PASSES_SANITIZE_LEAK=true
|
||||
|
||||
EMPTY=""
|
||||
|
||||
# test_commit_message <rev> -m <msg>
|
||||
# test_commit_message <rev> <path>
|
||||
# Verify that the commit message of <rev> matches
|
||||
# <msg> or the content of <path>.
|
||||
test_commit_message () {
|
||||
git show --no-patch --pretty=format:%B "$1" >actual &&
|
||||
case "$2" in
|
||||
-m)
|
||||
echo "$3" >expect &&
|
||||
test_cmp expect actual ;;
|
||||
*)
|
||||
test_cmp "$2" actual ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_author () {
|
||||
rev="$1" &&
|
||||
git log -1 --pretty=format:"%an %ae %at" "$rev"
|
||||
|
@ -232,10 +232,6 @@ test_expect_success 'diff --no-index refuses to diff stdin and a directory' '
|
||||
test_expect_success PIPE 'diff --no-index refuses to diff a named pipe and a directory' '
|
||||
test_when_finished "rm -f pipe" &&
|
||||
mkfifo pipe &&
|
||||
{
|
||||
(>pipe) &
|
||||
} &&
|
||||
test_when_finished "kill $!" &&
|
||||
test_must_fail git diff --no-index -- pipe a 2>err &&
|
||||
grep "fatal: cannot compare a named pipe to a directory" err
|
||||
'
|
||||
@ -248,11 +244,11 @@ test_expect_success PIPE,SYMLINKS 'diff --no-index reads from pipes' '
|
||||
{
|
||||
(test_write_lines a b c >old) &
|
||||
} &&
|
||||
test_when_finished "! kill $!" &&
|
||||
test_when_finished "kill $! || :" &&
|
||||
{
|
||||
(test_write_lines a x c >new) &
|
||||
} &&
|
||||
test_when_finished "! kill $!" &&
|
||||
test_when_finished "kill $! || :" &&
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
diff --git a/old b/new-link
|
||||
|
@ -466,7 +466,7 @@ test_expect_success 'gitmailmap(5) example output: example #1' '
|
||||
Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@laptop.(none)>
|
||||
Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
|
||||
|
||||
Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@desktop.(none)>
|
||||
Author Jane D. <jane@desktop.(none)> maps to Jane Doe <jane@desktop.(none)>
|
||||
Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
|
||||
EOF
|
||||
git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
|
||||
@ -494,7 +494,7 @@ test_expect_success 'gitmailmap(5) example output: example #2' '
|
||||
Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@example.com>
|
||||
Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
|
||||
|
||||
Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@example.com>
|
||||
Author Jane D. <jane@desktop.(none)> maps to Jane Doe <jane@example.com>
|
||||
Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
|
||||
EOF
|
||||
git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
|
||||
|
@ -24,12 +24,10 @@ test_expect_success 'usage shown with an error on unknown sub-command' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
objdir=".git/objects"
|
||||
|
||||
test_expect_success 'setup full repo' '
|
||||
mkdir full &&
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git init &&
|
||||
git config core.commitGraph true &&
|
||||
objdir=".git/objects"
|
||||
git init full
|
||||
'
|
||||
|
||||
test_expect_success POSIXPERM 'tweak umask for modebit tests' '
|
||||
@ -37,31 +35,28 @@ test_expect_success POSIXPERM 'tweak umask for modebit tests' '
|
||||
'
|
||||
|
||||
test_expect_success 'verify graph with no graph file' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph verify
|
||||
git -C full commit-graph verify
|
||||
'
|
||||
|
||||
test_expect_success 'write graph with no packs' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write --object-dir $objdir &&
|
||||
test_path_is_missing $objdir/info/commit-graph
|
||||
git -C full commit-graph write --object-dir $objdir &&
|
||||
test_path_is_missing full/$objdir/info/commit-graph
|
||||
'
|
||||
|
||||
test_expect_success 'exit with correct error on bad input to --stdin-packs' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
echo doesnotexist >in &&
|
||||
test_expect_code 1 git commit-graph write --stdin-packs <in 2>stderr &&
|
||||
test_expect_code 1 git -C full commit-graph write --stdin-packs \
|
||||
<in 2>stderr &&
|
||||
test_i18ngrep "error adding pack" stderr
|
||||
'
|
||||
|
||||
test_expect_success 'create commits and repack' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
for i in $(test_seq 3)
|
||||
do
|
||||
test_commit $i &&
|
||||
git branch commits/$i || return 1
|
||||
test_commit -C full $i &&
|
||||
git -C full branch commits/$i || return 1
|
||||
done &&
|
||||
git repack
|
||||
git -C full repack
|
||||
'
|
||||
|
||||
. "$TEST_DIRECTORY"/lib-commit-graph.sh
|
||||
@ -69,117 +64,106 @@ test_expect_success 'create commits and repack' '
|
||||
graph_git_behavior 'no graph' full commits/3 commits/1
|
||||
|
||||
test_expect_success 'exit with correct error on bad input to --stdin-commits' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
# invalid, non-hex OID
|
||||
echo HEAD >in &&
|
||||
test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr &&
|
||||
echo HEAD | test_expect_code 1 git -C full commit-graph write \
|
||||
--stdin-commits 2>stderr &&
|
||||
test_i18ngrep "unexpected non-hex object ID: HEAD" stderr &&
|
||||
# non-existent OID
|
||||
echo $ZERO_OID >in &&
|
||||
test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr &&
|
||||
echo $ZERO_OID | test_expect_code 1 git -C full commit-graph write \
|
||||
--stdin-commits 2>stderr &&
|
||||
test_i18ngrep "invalid object" stderr &&
|
||||
# valid commit and tree OID
|
||||
git rev-parse HEAD HEAD^{tree} >in &&
|
||||
git commit-graph write --stdin-commits <in &&
|
||||
graph_read_expect 3 generation_data
|
||||
git -C full rev-parse HEAD HEAD^{tree} >in &&
|
||||
git -C full commit-graph write --stdin-commits <in &&
|
||||
graph_read_expect -C full 3 generation_data
|
||||
'
|
||||
|
||||
test_expect_success 'write graph' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "3" generation_data
|
||||
git -C full commit-graph write &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 3 generation_data
|
||||
'
|
||||
|
||||
test_expect_success POSIXPERM 'write graph has correct permissions' '
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
echo "-r--r--r--" >expect &&
|
||||
test_modebits $objdir/info/commit-graph >actual &&
|
||||
test_modebits full/$objdir/info/commit-graph >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
graph_git_behavior 'graph exists' full commits/3 commits/1
|
||||
|
||||
test_expect_success 'Add more commits' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git reset --hard commits/1 &&
|
||||
git -C full reset --hard commits/1 &&
|
||||
for i in $(test_seq 4 5)
|
||||
do
|
||||
test_commit $i &&
|
||||
git branch commits/$i || return 1
|
||||
test_commit -C full $i &&
|
||||
git -C full branch commits/$i || return 1
|
||||
done &&
|
||||
git reset --hard commits/2 &&
|
||||
git -C full reset --hard commits/2 &&
|
||||
for i in $(test_seq 6 7)
|
||||
do
|
||||
test_commit $i &&
|
||||
git branch commits/$i || return 1
|
||||
test_commit -C full $i &&
|
||||
git -C full branch commits/$i || return 1
|
||||
done &&
|
||||
git reset --hard commits/2 &&
|
||||
git merge commits/4 &&
|
||||
git branch merge/1 &&
|
||||
git reset --hard commits/4 &&
|
||||
git merge commits/6 &&
|
||||
git branch merge/2 &&
|
||||
git reset --hard commits/3 &&
|
||||
git merge commits/5 commits/7 &&
|
||||
git branch merge/3 &&
|
||||
git repack
|
||||
git -C full reset --hard commits/2 &&
|
||||
git -C full merge commits/4 &&
|
||||
git -C full branch merge/1 &&
|
||||
git -C full reset --hard commits/4 &&
|
||||
git -C full merge commits/6 &&
|
||||
git -C full branch merge/2 &&
|
||||
git -C full reset --hard commits/3 &&
|
||||
git -C full merge commits/5 commits/7 &&
|
||||
git -C full branch merge/3 &&
|
||||
git -C full repack
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write progress off for redirected stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write 2>err &&
|
||||
git -C full commit-graph write 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write force progress on for stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
GIT_PROGRESS_DELAY=0 git commit-graph write --progress 2>err &&
|
||||
GIT_PROGRESS_DELAY=0 git -C full commit-graph write --progress 2>err &&
|
||||
test_file_not_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write with the --no-progress option' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write --no-progress 2>err &&
|
||||
git -C full commit-graph write --no-progress 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write --stdin-commits progress off for redirected stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git rev-parse commits/5 >in &&
|
||||
git commit-graph write --stdin-commits <in 2>err &&
|
||||
git -C full rev-parse commits/5 >in &&
|
||||
git -C full commit-graph write --stdin-commits <in 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write --stdin-commits force progress on for stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git rev-parse commits/5 >in &&
|
||||
GIT_PROGRESS_DELAY=0 git commit-graph write --stdin-commits --progress <in 2>err &&
|
||||
git -C full rev-parse commits/5 >in &&
|
||||
GIT_PROGRESS_DELAY=0 git -C full commit-graph write --stdin-commits \
|
||||
--progress <in 2>err &&
|
||||
test_i18ngrep "Collecting commits from input" err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph write --stdin-commits with the --no-progress option' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git rev-parse commits/5 >in &&
|
||||
git commit-graph write --stdin-commits --no-progress <in 2>err &&
|
||||
git -C full rev-parse commits/5 >in &&
|
||||
git -C full commit-graph write --stdin-commits --no-progress <in 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph verify progress off for redirected stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph verify 2>err &&
|
||||
git -C full commit-graph verify 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph verify force progress on for stderr' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
GIT_PROGRESS_DELAY=0 git commit-graph verify --progress 2>err &&
|
||||
GIT_PROGRESS_DELAY=0 git -C full commit-graph verify --progress 2>err &&
|
||||
test_file_not_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'commit-graph verify with the --no-progress option' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph verify --no-progress 2>err &&
|
||||
git -C full commit-graph verify --no-progress 2>err &&
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
@ -194,10 +178,9 @@ test_expect_success 'commit-graph verify with the --no-progress option' '
|
||||
# 1
|
||||
|
||||
test_expect_success 'write graph with merges' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "10" "generation_data extra_edges"
|
||||
git -C full commit-graph write &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 10 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2
|
||||
@ -205,12 +188,11 @@ graph_git_behavior 'merge 1 vs 3' full merge/1 merge/3
|
||||
graph_git_behavior 'merge 2 vs 3' full merge/2 merge/3
|
||||
|
||||
test_expect_success 'Add one more commit' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
test_commit 8 &&
|
||||
git branch commits/8 &&
|
||||
ls $objdir/pack | grep idx >existing-idx &&
|
||||
git repack &&
|
||||
ls $objdir/pack| grep idx | grep -v -f existing-idx >new-idx
|
||||
test_commit -C full 8 &&
|
||||
git -C full branch commits/8 &&
|
||||
ls full/$objdir/pack | grep idx >existing-idx &&
|
||||
git -C full repack &&
|
||||
ls full/$objdir/pack| grep idx | grep -v -f existing-idx >new-idx
|
||||
'
|
||||
|
||||
# Current graph structure:
|
||||
@ -229,114 +211,101 @@ graph_git_behavior 'mixed mode, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'mixed mode, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'write graph with new commit' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "11" "generation_data extra_edges"
|
||||
git -C full commit-graph write &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 11 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'full graph, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'write graph with nothing new' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "11" "generation_data extra_edges"
|
||||
git -C full commit-graph write &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 11 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'cleared graph, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'build graph from latest pack with closure' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
cat new-idx | git commit-graph write --stdin-packs &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "9" "generation_data extra_edges"
|
||||
git -C full commit-graph write --stdin-packs <new-idx &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 9 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'graph from pack, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'build graph from commits with closure' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git tag -a -m "merge" tag/merge merge/2 &&
|
||||
git rev-parse tag/merge >commits-in &&
|
||||
git rev-parse merge/1 >>commits-in &&
|
||||
cat commits-in | git commit-graph write --stdin-commits &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "6" "generation_data"
|
||||
git -C full tag -a -m "merge" tag/merge merge/2 &&
|
||||
git -C full rev-parse tag/merge >commits-in &&
|
||||
git -C full rev-parse merge/1 >>commits-in &&
|
||||
git -C full commit-graph write --stdin-commits <commits-in &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 6 "generation_data"
|
||||
'
|
||||
|
||||
graph_git_behavior 'graph from commits, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'graph from commits, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'build graph from commits with append' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git rev-parse merge/3 | git commit-graph write --stdin-commits --append &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "10" "generation_data extra_edges"
|
||||
git -C full rev-parse merge/3 >in &&
|
||||
git -C full commit-graph write --stdin-commits --append <in &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 10 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'build graph using --reachable' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write --reachable &&
|
||||
test_path_is_file $objdir/info/commit-graph &&
|
||||
graph_read_expect "11" "generation_data extra_edges"
|
||||
git -C full commit-graph write --reachable &&
|
||||
test_path_is_file full/$objdir/info/commit-graph &&
|
||||
graph_read_expect -C full 11 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
|
||||
graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2
|
||||
|
||||
test_expect_success 'setup bare repo' '
|
||||
cd "$TRASH_DIRECTORY" &&
|
||||
git clone --bare --no-local full bare &&
|
||||
cd bare &&
|
||||
git config core.commitGraph true &&
|
||||
baredir="./objects"
|
||||
git clone --bare --no-local full bare
|
||||
'
|
||||
|
||||
graph_git_behavior 'bare repo, commit 8 vs merge 1' bare commits/8 merge/1
|
||||
graph_git_behavior 'bare repo, commit 8 vs merge 2' bare commits/8 merge/2
|
||||
|
||||
test_expect_success 'write graph in bare repo' '
|
||||
cd "$TRASH_DIRECTORY/bare" &&
|
||||
git commit-graph write &&
|
||||
test_path_is_file $baredir/info/commit-graph &&
|
||||
graph_read_expect "11" "generation_data extra_edges"
|
||||
git -C bare commit-graph write &&
|
||||
test_path_is_file bare/objects/info/commit-graph &&
|
||||
graph_read_expect -C bare 11 "generation_data extra_edges"
|
||||
'
|
||||
|
||||
graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1
|
||||
graph_git_behavior 'bare repo with graph, commit 8 vs merge 2' bare commits/8 merge/2
|
||||
|
||||
test_expect_success 'perform fast-forward merge in full repo' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git checkout -b merge-5-to-8 commits/5 &&
|
||||
git merge commits/8 &&
|
||||
git show-ref -s merge-5-to-8 >output &&
|
||||
git show-ref -s commits/8 >expect &&
|
||||
git -C full checkout -b merge-5-to-8 commits/5 &&
|
||||
git -C full merge commits/8 &&
|
||||
git -C full show-ref -s merge-5-to-8 >output &&
|
||||
git -C full show-ref -s commits/8 >expect &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success 'check that gc computes commit-graph' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit --allow-empty -m "blank" &&
|
||||
git commit-graph write --reachable &&
|
||||
cp $objdir/info/commit-graph commit-graph-before-gc &&
|
||||
git reset --hard HEAD~1 &&
|
||||
git config gc.writeCommitGraph true &&
|
||||
git gc &&
|
||||
cp $objdir/info/commit-graph commit-graph-after-gc &&
|
||||
test_commit -C full --no-tag blank &&
|
||||
git -C full commit-graph write --reachable &&
|
||||
cp full/$objdir/info/commit-graph commit-graph-before-gc &&
|
||||
git -C full reset --hard HEAD~1 &&
|
||||
test_config -C full gc.writeCommitGraph true &&
|
||||
git -C full gc &&
|
||||
cp full/$objdir/info/commit-graph commit-graph-after-gc &&
|
||||
! test_cmp_bin commit-graph-before-gc commit-graph-after-gc &&
|
||||
git commit-graph write --reachable &&
|
||||
test_cmp_bin commit-graph-after-gc $objdir/info/commit-graph
|
||||
git -C full commit-graph write --reachable &&
|
||||
test_cmp_bin commit-graph-after-gc full/$objdir/info/commit-graph
|
||||
'
|
||||
|
||||
test_expect_success 'replace-objects invalidates commit-graph' '
|
||||
cd "$TRASH_DIRECTORY" &&
|
||||
test_when_finished rm -rf replace &&
|
||||
git clone full replace &&
|
||||
(
|
||||
@ -359,7 +328,6 @@ test_expect_success 'replace-objects invalidates commit-graph' '
|
||||
'
|
||||
|
||||
test_expect_success 'commit grafts invalidate commit-graph' '
|
||||
cd "$TRASH_DIRECTORY" &&
|
||||
test_when_finished rm -rf graft &&
|
||||
git clone --template= full graft &&
|
||||
(
|
||||
@ -384,7 +352,6 @@ test_expect_success 'commit grafts invalidate commit-graph' '
|
||||
'
|
||||
|
||||
test_expect_success 'replace-objects invalidates commit-graph' '
|
||||
cd "$TRASH_DIRECTORY" &&
|
||||
test_when_finished rm -rf shallow &&
|
||||
git clone --depth 2 "file://$TRASH_DIRECTORY/full" shallow &&
|
||||
(
|
||||
@ -427,24 +394,25 @@ test_expect_success 'warn on improper hash version' '
|
||||
'
|
||||
|
||||
test_expect_success TIME_IS_64BIT,TIME_T_IS_64BIT 'lower layers have overflow chunk' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
UNIX_EPOCH_ZERO="@0 +0000" &&
|
||||
FUTURE_DATE="@4147483646 +0000" &&
|
||||
rm -f .git/objects/info/commit-graph &&
|
||||
test_commit --date "$FUTURE_DATE" future-1 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" old-1 &&
|
||||
git commit-graph write --reachable &&
|
||||
test_commit --date "$FUTURE_DATE" future-2 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" old-2 &&
|
||||
git commit-graph write --reachable --split=no-merge &&
|
||||
test_commit extra &&
|
||||
git commit-graph write --reachable --split=no-merge &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 16 "generation_data generation_data_overflow extra_edges" &&
|
||||
mv .git/objects/info/commit-graph commit-graph-upgraded &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 16 "generation_data generation_data_overflow extra_edges" &&
|
||||
test_cmp .git/objects/info/commit-graph commit-graph-upgraded
|
||||
rm -f full/.git/objects/info/commit-graph &&
|
||||
test_commit -C full --date "$FUTURE_DATE" future-1 &&
|
||||
test_commit -C full --date "$UNIX_EPOCH_ZERO" old-1 &&
|
||||
git -C full commit-graph write --reachable &&
|
||||
test_commit -C full --date "$FUTURE_DATE" future-2 &&
|
||||
test_commit -C full --date "$UNIX_EPOCH_ZERO" old-2 &&
|
||||
git -C full commit-graph write --reachable --split=no-merge &&
|
||||
test_commit -C full extra &&
|
||||
git -C full commit-graph write --reachable --split=no-merge &&
|
||||
git -C full commit-graph write --reachable &&
|
||||
graph_read_expect -C full 16 \
|
||||
"generation_data generation_data_overflow extra_edges" &&
|
||||
mv full/.git/objects/info/commit-graph commit-graph-upgraded &&
|
||||
git -C full commit-graph write --reachable &&
|
||||
graph_read_expect -C full 16 \
|
||||
"generation_data generation_data_overflow extra_edges" &&
|
||||
test_cmp full/.git/objects/info/commit-graph commit-graph-upgraded
|
||||
'
|
||||
|
||||
# the verify tests below expect the commit-graph to contain
|
||||
@ -454,10 +422,11 @@ test_expect_success TIME_IS_64BIT,TIME_T_IS_64BIT 'lower layers have overflow ch
|
||||
# and the tests will likely break.
|
||||
|
||||
test_expect_success 'git commit-graph verify' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git rev-parse commits/8 | git -c commitGraph.generationVersion=1 commit-graph write --stdin-commits &&
|
||||
git commit-graph verify >output &&
|
||||
graph_read_expect 9 extra_edges 1
|
||||
git -C full rev-parse commits/8 >in &&
|
||||
git -C full -c commitGraph.generationVersion=1 commit-graph write \
|
||||
--stdin-commits <in &&
|
||||
git -C full commit-graph verify >output &&
|
||||
graph_read_expect -C full 9 extra_edges 1
|
||||
'
|
||||
|
||||
NUM_COMMITS=9
|
||||
@ -495,25 +464,24 @@ GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4))
|
||||
GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES))
|
||||
|
||||
corrupt_graph_setup() {
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
test_when_finished mv commit-graph-backup $objdir/info/commit-graph &&
|
||||
cp $objdir/info/commit-graph commit-graph-backup &&
|
||||
chmod u+w $objdir/info/commit-graph
|
||||
test_when_finished mv commit-graph-backup full/$objdir/info/commit-graph &&
|
||||
cp full/$objdir/info/commit-graph commit-graph-backup &&
|
||||
chmod u+w full/$objdir/info/commit-graph
|
||||
}
|
||||
|
||||
corrupt_graph_verify() {
|
||||
grepstr=$1
|
||||
test_must_fail git commit-graph verify 2>test_err &&
|
||||
test_must_fail git -C full commit-graph verify 2>test_err &&
|
||||
grep -v "^+" test_err >err &&
|
||||
test_i18ngrep "$grepstr" err &&
|
||||
if test "$2" != "no-copy"
|
||||
then
|
||||
cp $objdir/info/commit-graph commit-graph-pre-write-test
|
||||
cp full/$objdir/info/commit-graph commit-graph-pre-write-test
|
||||
fi &&
|
||||
git status --short &&
|
||||
GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git commit-graph write &&
|
||||
chmod u+w $objdir/info/commit-graph &&
|
||||
git commit-graph verify
|
||||
git -C full status --short &&
|
||||
GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git -C full commit-graph write &&
|
||||
chmod u+w full/$objdir/info/commit-graph &&
|
||||
git -C full commit-graph verify
|
||||
}
|
||||
|
||||
# usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>]
|
||||
@ -527,24 +495,24 @@ corrupt_graph_and_verify() {
|
||||
data="${2:-\0}"
|
||||
grepstr=$3
|
||||
corrupt_graph_setup &&
|
||||
orig_size=$(wc -c < $objdir/info/commit-graph) &&
|
||||
orig_size=$(wc -c <full/$objdir/info/commit-graph) &&
|
||||
zero_pos=${4:-${orig_size}} &&
|
||||
printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc &&
|
||||
dd of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null &&
|
||||
test-tool genzeros $(($orig_size - $zero_pos)) >>"$objdir/info/commit-graph" &&
|
||||
printf "$data" | dd of="full/$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc &&
|
||||
dd of="full/$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null &&
|
||||
test-tool genzeros $(($orig_size - $zero_pos)) >>"full/$objdir/info/commit-graph" &&
|
||||
corrupt_graph_verify "$grepstr"
|
||||
|
||||
}
|
||||
|
||||
test_expect_success POSIXPERM,SANITY 'detect permission problem' '
|
||||
corrupt_graph_setup &&
|
||||
chmod 000 $objdir/info/commit-graph &&
|
||||
chmod 000 full/$objdir/info/commit-graph &&
|
||||
corrupt_graph_verify "Could not open" "no-copy"
|
||||
'
|
||||
|
||||
test_expect_success 'detect too small' '
|
||||
corrupt_graph_setup &&
|
||||
echo "a small graph" >$objdir/info/commit-graph &&
|
||||
echo "a small graph" >full/$objdir/info/commit-graph &&
|
||||
corrupt_graph_verify "too small"
|
||||
'
|
||||
|
||||
@ -655,33 +623,30 @@ test_expect_success 'detect incorrect chunk count' '
|
||||
'
|
||||
|
||||
test_expect_success 'git fsck (checks commit-graph when config set to true)' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git fsck &&
|
||||
git -C full fsck &&
|
||||
corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \
|
||||
"incorrect checksum" &&
|
||||
cp commit-graph-pre-write-test $objdir/info/commit-graph &&
|
||||
test_must_fail git -c core.commitGraph=true fsck
|
||||
cp commit-graph-pre-write-test full/$objdir/info/commit-graph &&
|
||||
test_must_fail git -C full -c core.commitGraph=true fsck
|
||||
'
|
||||
|
||||
test_expect_success 'git fsck (ignores commit-graph when config set to false)' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git fsck &&
|
||||
git -C full fsck &&
|
||||
corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \
|
||||
"incorrect checksum" &&
|
||||
cp commit-graph-pre-write-test $objdir/info/commit-graph &&
|
||||
git -c core.commitGraph=false fsck
|
||||
cp commit-graph-pre-write-test full/$objdir/info/commit-graph &&
|
||||
git -C full -c core.commitGraph=false fsck
|
||||
'
|
||||
|
||||
test_expect_success 'git fsck (checks commit-graph when config unset)' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
test_when_finished "git config core.commitGraph true" &&
|
||||
test_when_finished "git -C full config core.commitGraph true" &&
|
||||
|
||||
git fsck &&
|
||||
git -C full fsck &&
|
||||
corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \
|
||||
"incorrect checksum" &&
|
||||
test_unconfig core.commitGraph &&
|
||||
cp commit-graph-pre-write-test $objdir/info/commit-graph &&
|
||||
test_must_fail git fsck
|
||||
test_unconfig -C full core.commitGraph &&
|
||||
cp commit-graph-pre-write-test full/$objdir/info/commit-graph &&
|
||||
test_must_fail git -C full fsck
|
||||
'
|
||||
|
||||
test_expect_success 'git fsck shows commit-graph output with --progress' '
|
||||
@ -792,32 +757,33 @@ test_expect_success 'corrupt commit-graph write (missing tree)' '
|
||||
#
|
||||
|
||||
test_expect_success 'set up and verify repo with generation data overflow chunk' '
|
||||
objdir=".git/objects" &&
|
||||
UNIX_EPOCH_ZERO="@0 +0000" &&
|
||||
FUTURE_DATE="@2147483646 +0000" &&
|
||||
cd "$TRASH_DIRECTORY" &&
|
||||
mkdir repo &&
|
||||
cd repo &&
|
||||
git init &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 3 &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 3 generation_data &&
|
||||
test_commit --date "$FUTURE_DATE" 4 &&
|
||||
test_commit 5 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 6 &&
|
||||
git branch left &&
|
||||
git reset --hard 3 &&
|
||||
test_commit 7 &&
|
||||
test_commit --date "$FUTURE_DATE" 8 &&
|
||||
test_commit 9 &&
|
||||
git branch right &&
|
||||
git reset --hard 3 &&
|
||||
test_merge M left right &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 10 "generation_data generation_data_overflow" &&
|
||||
git commit-graph verify
|
||||
|
||||
git init repo &&
|
||||
(
|
||||
cd repo &&
|
||||
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 3 &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 3 generation_data &&
|
||||
test_commit --date "$FUTURE_DATE" 4 &&
|
||||
test_commit 5 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 6 &&
|
||||
git branch left &&
|
||||
git reset --hard 3 &&
|
||||
test_commit 7 &&
|
||||
test_commit --date "$FUTURE_DATE" 8 &&
|
||||
test_commit 9 &&
|
||||
git branch right &&
|
||||
git reset --hard 3 &&
|
||||
test_merge M left right &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 10 "generation_data generation_data_overflow" &&
|
||||
git commit-graph verify
|
||||
)
|
||||
'
|
||||
|
||||
graph_git_behavior 'generation data overflow chunk repo' repo left right
|
||||
|
@ -37,39 +37,39 @@ test_expect_success 'lower layers have overflow chunk' '
|
||||
graph_git_behavior 'overflow' '' HEAD~2 HEAD
|
||||
|
||||
test_expect_success 'set up and verify repo with generation data overflow chunk' '
|
||||
mkdir repo &&
|
||||
cd repo &&
|
||||
git init &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 3 &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 3 generation_data &&
|
||||
test_commit --date "$FUTURE_DATE" 4 &&
|
||||
test_commit 5 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 6 &&
|
||||
git branch left &&
|
||||
git reset --hard 3 &&
|
||||
test_commit 7 &&
|
||||
test_commit --date "$FUTURE_DATE" 8 &&
|
||||
test_commit 9 &&
|
||||
git branch right &&
|
||||
git reset --hard 3 &&
|
||||
test_merge M left right &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 10 "generation_data generation_data_overflow" &&
|
||||
git commit-graph verify
|
||||
git init repo &&
|
||||
(
|
||||
cd repo &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 3 &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 3 generation_data &&
|
||||
test_commit --date "$FUTURE_DATE" 4 &&
|
||||
test_commit 5 &&
|
||||
test_commit --date "$UNIX_EPOCH_ZERO" 6 &&
|
||||
git branch left &&
|
||||
git reset --hard 3 &&
|
||||
test_commit 7 &&
|
||||
test_commit --date "$FUTURE_DATE" 8 &&
|
||||
test_commit 9 &&
|
||||
git branch right &&
|
||||
git reset --hard 3 &&
|
||||
test_merge M left right &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 10 "generation_data generation_data_overflow" &&
|
||||
git commit-graph verify
|
||||
)
|
||||
'
|
||||
|
||||
graph_git_behavior 'overflow 2' repo left right
|
||||
|
||||
test_expect_success 'single commit with generation data exceeding UINT32_MAX' '
|
||||
git init repo-uint32-max &&
|
||||
cd repo-uint32-max &&
|
||||
test_commit --date "@4294967297 +0000" 1 &&
|
||||
git commit-graph write --reachable &&
|
||||
graph_read_expect 1 "generation_data" &&
|
||||
git commit-graph verify
|
||||
test_commit -C repo-uint32-max --date "@4294967297 +0000" 1 &&
|
||||
git -C repo-uint32-max commit-graph write --reachable &&
|
||||
graph_read_expect -C repo-uint32-max 1 "generation_data" &&
|
||||
git -C repo-uint32-max commit-graph verify
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -619,6 +619,12 @@ test_expect_success TTY 'create --quiet disables all bundle progress' '
|
||||
test_must_be_empty err
|
||||
'
|
||||
|
||||
test_expect_success 'bundle progress with --no-quiet' '
|
||||
GIT_PROGRESS_DELAY=0 \
|
||||
git bundle create --no-quiet out.bundle --all 2>err &&
|
||||
grep "%" err
|
||||
'
|
||||
|
||||
test_expect_success 'read bundle over stdin' '
|
||||
git bundle create some.bundle HEAD &&
|
||||
|
||||
|
@ -174,6 +174,13 @@ test_expect_success 'do not move directory over existing directory' '
|
||||
test_must_fail git mv path2 path0
|
||||
'
|
||||
|
||||
test_expect_success 'rename directory to non-existing directory' '
|
||||
mkdir dir-a &&
|
||||
>dir-a/f &&
|
||||
git add dir-a &&
|
||||
git mv dir-a non-existing-dir
|
||||
'
|
||||
|
||||
test_expect_success 'move into "."' '
|
||||
git mv path1/path2/ .
|
||||
'
|
||||
|
@ -20,10 +20,19 @@ test_expect_success 'empty name and missing email' '
|
||||
'
|
||||
|
||||
test_expect_success 'commit rejects all-crud name' '
|
||||
test_must_fail env GIT_AUTHOR_NAME=" .;<>" \
|
||||
test_must_fail env GIT_AUTHOR_NAME=" ,;<>" \
|
||||
git commit --allow-empty -m foo
|
||||
'
|
||||
|
||||
test_expect_success 'commit does not strip trailing dot' '
|
||||
author_name="Pat Doe Jr." &&
|
||||
env GIT_AUTHOR_NAME="$author_name" \
|
||||
git commit --allow-empty -m foo &&
|
||||
git log -1 --format=%an >actual &&
|
||||
echo "$author_name" >expected &&
|
||||
test_cmp actual expected
|
||||
'
|
||||
|
||||
# We must test the actual error message here, as an unwanted
|
||||
# auto-detection could fail for other reasons.
|
||||
test_expect_success 'empty configured name does not auto-detect' '
|
||||
|
@ -337,13 +337,14 @@ test_expect_success $PREREQ 'Show all headers' '
|
||||
test_expect_success $PREREQ 'Prompting works' '
|
||||
clean_fake_sendmail &&
|
||||
(echo "to@example.com" &&
|
||||
echo ""
|
||||
echo "my-message-id@example.com"
|
||||
) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
|
||||
--smtp-server="$(pwd)/fake.sendmail" \
|
||||
$patches \
|
||||
2>errors &&
|
||||
grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
|
||||
grep "^To: to@example.com\$" msgtxt1
|
||||
grep "^To: to@example.com\$" msgtxt1 &&
|
||||
grep "^In-Reply-To: <my-message-id@example.com>" msgtxt1
|
||||
'
|
||||
|
||||
test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' '
|
||||
@ -659,7 +660,6 @@ test_expect_success $PREREQ 'clear message-id before parsing a new message' '
|
||||
clean_fake_sendmail &&
|
||||
echo true | write_script my-hooks/sendemail-validate &&
|
||||
test_config core.hooksPath my-hooks &&
|
||||
GIT_SEND_EMAIL_NOTTY=1 \
|
||||
git send-email --validate --to=recipient@example.com \
|
||||
--smtp-server="$(pwd)/fake.sendmail" \
|
||||
$patches $threaded_patches &&
|
||||
|
@ -1291,6 +1291,39 @@ test_cmp_rev () {
|
||||
fi
|
||||
}
|
||||
|
||||
# Tests that a commit message matches the expected text
|
||||
#
|
||||
# Usage: test_commit_message <rev> [-m <msg> | <file>]
|
||||
#
|
||||
# When using "-m" <msg> will have a line feed appended. If the second
|
||||
# argument is omitted then the expected message is read from stdin.
|
||||
|
||||
test_commit_message () {
|
||||
local msg_file=expect.msg
|
||||
|
||||
case $# in
|
||||
3)
|
||||
if test "$2" = "-m"
|
||||
then
|
||||
printf "%s\n" "$3" >"$msg_file"
|
||||
else
|
||||
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
msg_file="$2"
|
||||
;;
|
||||
1)
|
||||
cat >"$msg_file"
|
||||
;;
|
||||
*)
|
||||
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
|
||||
;;
|
||||
esac
|
||||
git show --no-patch --pretty=format:%B "$1" -- >actual.msg &&
|
||||
test_cmp "$msg_file" actual.msg
|
||||
}
|
||||
|
||||
# Compare paths respecting core.ignoreCase
|
||||
test_cmp_fspath () {
|
||||
if test "x$1" = "x$2"
|
||||
|
Loading…
Reference in New Issue
Block a user