Compare commits
46 Commits
Author | SHA1 | Date | |
---|---|---|---|
a2558fb8e1 | |||
6343e2f6f2 | |||
18b58f707f | |||
92cdfd2131 | |||
83c4d38017 | |||
dcd1742e56 | |||
3efb988098 | |||
f2df3104ce | |||
df37727a65 | |||
b258116462 | |||
f4113cac0c | |||
5088d3b387 | |||
33cfccbbf3 | |||
a5adaced2e | |||
74b6763816 | |||
ef0e938a1a | |||
ecad27cf98 | |||
8267cd11d6 | |||
441c4a4017 | |||
f54cb059b1 | |||
78f23bdf68 | |||
5015f01c12 | |||
c29edfefb6 | |||
f514ef9787 | |||
8545932d45 | |||
29dce32f79 | |||
de67af4a8f | |||
44737c4228 | |||
c36e465aca | |||
0533a9b70c | |||
a94594dcf7 | |||
7e837c6477 | |||
0e0aff4b4c | |||
d17ec3a9da | |||
fbfa0973fa | |||
6ea3b67b4e | |||
e06764c8eb | |||
20c3fe7621 | |||
f8da6801e2 | |||
2c970c9ec3 | |||
88d5072466 | |||
501cf47cdd | |||
72dbb36554 | |||
f5517074f8 | |||
8afc493d11 | |||
c3e23dc117 |
9
Documentation/RelNotes/2.2.3.txt
Normal file
9
Documentation/RelNotes/2.2.3.txt
Normal file
@ -0,0 +1,9 @@
|
||||
Git v2.2.3 Release Notes
|
||||
========================
|
||||
|
||||
Fixes since v2.2.2
|
||||
------------------
|
||||
|
||||
* A handful of codepaths that used to use fixed-sized arrays to hold
|
||||
pathnames have been corrected to use strbuf and other mechanisms to
|
||||
allow longer pathnames without fearing overflows.
|
18
Documentation/RelNotes/2.3.10.txt
Normal file
18
Documentation/RelNotes/2.3.10.txt
Normal file
@ -0,0 +1,18 @@
|
||||
Git v2.3.10 Release Notes
|
||||
=========================
|
||||
|
||||
Fixes since v2.3.9
|
||||
------------------
|
||||
|
||||
* xdiff code we use to generate diffs is not prepared to handle
|
||||
extremely large files. It uses "int" in many places, which can
|
||||
overflow if we have a very large number of lines or even bytes in
|
||||
our input files, for example. Cap the input size to soemwhere
|
||||
around 1GB for now.
|
||||
|
||||
* Some protocols (like git-remote-ext) can execute arbitrary code
|
||||
found in the URL. The URLs that submodules use may come from
|
||||
arbitrary sources (e.g., .gitmodules files in a remote
|
||||
repository), and can hurt those who blindly enable recursive
|
||||
fetch. Restrict the allowed protocols to well known and safe
|
||||
ones.
|
9
Documentation/RelNotes/2.3.9.txt
Normal file
9
Documentation/RelNotes/2.3.9.txt
Normal file
@ -0,0 +1,9 @@
|
||||
Git v2.3.9 Release Notes
|
||||
========================
|
||||
|
||||
Fixes since v2.3.8
|
||||
------------------
|
||||
|
||||
* A handful of codepaths that used to use fixed-sized arrays to hold
|
||||
pathnames have been corrected to use strbuf and other mechanisms to
|
||||
allow longer pathnames without fearing overflows.
|
18
Documentation/RelNotes/2.4.10.txt
Normal file
18
Documentation/RelNotes/2.4.10.txt
Normal file
@ -0,0 +1,18 @@
|
||||
Git v2.4.10 Release Notes
|
||||
=========================
|
||||
|
||||
Fixes since v2.4.9
|
||||
------------------
|
||||
|
||||
* xdiff code we use to generate diffs is not prepared to handle
|
||||
extremely large files. It uses "int" in many places, which can
|
||||
overflow if we have a very large number of lines or even bytes in
|
||||
our input files, for example. Cap the input size to soemwhere
|
||||
around 1GB for now.
|
||||
|
||||
* Some protocols (like git-remote-ext) can execute arbitrary code
|
||||
found in the URL. The URLs that submodules use may come from
|
||||
arbitrary sources (e.g., .gitmodules files in a remote
|
||||
repository), and can hurt those who blindly enable recursive
|
||||
fetch. Restrict the allowed protocols to well known and safe
|
||||
ones.
|
21
Documentation/RelNotes/2.4.8.txt
Normal file
21
Documentation/RelNotes/2.4.8.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Git v2.4.8 Release Notes
|
||||
========================
|
||||
|
||||
Fixes since v2.4.7
|
||||
------------------
|
||||
|
||||
* Abandoning an already applied change in "git rebase -i" with
|
||||
"--continue" left CHERRY_PICK_HEAD and confused later steps.
|
||||
|
||||
* Various fixes around "git am" that applies a patch to a history
|
||||
that is not there yet.
|
||||
|
||||
* "git for-each-ref" reported "missing object" for 0{40} when it
|
||||
encounters a broken ref. The lack of object whose name is 0{40} is
|
||||
not the problem; the ref being broken is.
|
||||
|
||||
* "git commit --cleanup=scissors" was not careful enough to protect
|
||||
against getting fooled by a line that looked like scissors.
|
||||
|
||||
Also contains typofixes, documentation updates and trivial code
|
||||
clean-ups.
|
9
Documentation/RelNotes/2.4.9.txt
Normal file
9
Documentation/RelNotes/2.4.9.txt
Normal file
@ -0,0 +1,9 @@
|
||||
Git v2.4.9 Release Notes
|
||||
========================
|
||||
|
||||
Fixes since v2.4.9
|
||||
------------------
|
||||
|
||||
* A handful of codepaths that used to use fixed-sized arrays to hold
|
||||
pathnames have been corrected to use strbuf and other mechanisms to
|
||||
allow longer pathnames without fearing overflows.
|
@ -43,9 +43,12 @@ unreleased) version of Git, that is available from the 'master'
|
||||
branch of the `git.git` repository.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v2.4.7/git.html[documentation for release 2.4.7]
|
||||
* link:v2.4.10/git.html[documentation for release 2.4.10]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes/2.4.10.txt[2.4.10],
|
||||
link:RelNotes/2.4.9.txt[2.4.9],
|
||||
link:RelNotes/2.4.8.txt[2.4.8],
|
||||
link:RelNotes/2.4.7.txt[2.4.7],
|
||||
link:RelNotes/2.4.6.txt[2.4.6],
|
||||
link:RelNotes/2.4.5.txt[2.4.5],
|
||||
@ -55,9 +58,11 @@ Documentation for older releases are available here:
|
||||
link:RelNotes/2.4.1.txt[2.4.1],
|
||||
link:RelNotes/2.4.0.txt[2.4].
|
||||
|
||||
* link:v2.3.8/git.html[documentation for release 2.3.8]
|
||||
* link:v2.3.10/git.html[documentation for release 2.3.10]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes/2.3.10.txt[2.3.10],
|
||||
link:RelNotes/2.3.9.txt[2.3.9],
|
||||
link:RelNotes/2.3.8.txt[2.3.8],
|
||||
link:RelNotes/2.3.7.txt[2.3.7],
|
||||
link:RelNotes/2.3.6.txt[2.3.6],
|
||||
@ -68,9 +73,10 @@ Documentation for older releases are available here:
|
||||
link:RelNotes/2.3.1.txt[2.3.1],
|
||||
link:RelNotes/2.3.0.txt[2.3].
|
||||
|
||||
* link:v2.2.2/git.html[documentation for release 2.2.2]
|
||||
* link:v2.2.3/git.html[documentation for release 2.2.3]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes/2.2.3.txt[2.2.3],
|
||||
link:RelNotes/2.2.2.txt[2.2.2],
|
||||
link:RelNotes/2.2.1.txt[2.2.1],
|
||||
link:RelNotes/2.2.0.txt[2.2].
|
||||
@ -1055,6 +1061,33 @@ GIT_ICASE_PATHSPECS::
|
||||
an operation has touched every ref (e.g., because you are
|
||||
cloning a repository to make a backup).
|
||||
|
||||
`GIT_ALLOW_PROTOCOL`::
|
||||
If set, provide a colon-separated list of protocols which are
|
||||
allowed to be used with fetch/push/clone. This is useful to
|
||||
restrict recursive submodule initialization from an untrusted
|
||||
repository. Any protocol not mentioned will be disallowed (i.e.,
|
||||
this is a whitelist, not a blacklist). If the variable is not
|
||||
set at all, all protocols are enabled. The protocol names
|
||||
currently used by git are:
|
||||
|
||||
- `file`: any local file-based path (including `file://` URLs,
|
||||
or local paths)
|
||||
|
||||
- `git`: the anonymous git protocol over a direct TCP
|
||||
connection (or proxy, if configured)
|
||||
|
||||
- `ssh`: git over ssh (including `host:path` syntax,
|
||||
`git+ssh://`, etc).
|
||||
|
||||
- `rsync`: git over rsync
|
||||
|
||||
- `http`: git over http, both "smart http" and "dumb http".
|
||||
Note that this does _not_ include `https`; if you want both,
|
||||
you should specify both as `http:https`.
|
||||
|
||||
- any external helpers are named by their protocol (e.g., use
|
||||
`hg` to allow the `git-remote-hg` helper)
|
||||
|
||||
|
||||
Discussion[[Discussion]]
|
||||
------------------------
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v2.4.7
|
||||
DEF_VER=v2.4.10
|
||||
|
||||
LF='
|
||||
'
|
||||
@ -38,5 +38,3 @@ test "$VN" = "$VC" || {
|
||||
echo >&2 "GIT_VERSION = $VN"
|
||||
echo "GIT_VERSION = $VN" >$GVF
|
||||
}
|
||||
|
||||
|
||||
|
@ -973,7 +973,10 @@ static void pass_blame_to_parent(struct scoreboard *sb,
|
||||
fill_origin_blob(&sb->revs->diffopt, target, &file_o);
|
||||
num_get_patch++;
|
||||
|
||||
diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d);
|
||||
if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
|
||||
die("unable to generate diff (%s -> %s)",
|
||||
sha1_to_hex(parent->commit->object.sha1),
|
||||
sha1_to_hex(target->commit->object.sha1));
|
||||
/* The rest are the same as the parent */
|
||||
blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
|
||||
*d.dstq = NULL;
|
||||
@ -1119,7 +1122,9 @@ static void find_copy_in_blob(struct scoreboard *sb,
|
||||
* file_p partially may match that image.
|
||||
*/
|
||||
memset(split, 0, sizeof(struct blame_entry [3]));
|
||||
diff_hunks(file_p, &file_o, 1, handle_split_cb, &d);
|
||||
if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
|
||||
die("unable to generate diff (%s)",
|
||||
sha1_to_hex(parent->commit->object.sha1));
|
||||
/* remainder, if any, all match the preimage */
|
||||
handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle)
|
||||
static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
|
||||
{
|
||||
const char *end = repo + strlen(repo), *start;
|
||||
size_t len;
|
||||
char *dir;
|
||||
|
||||
/*
|
||||
@ -173,20 +174,12 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
|
||||
/*
|
||||
* Strip .{bundle,git}.
|
||||
*/
|
||||
if (is_bundle) {
|
||||
if (end - start > 7 && !strncmp(end - 7, ".bundle", 7))
|
||||
end -= 7;
|
||||
} else {
|
||||
if (end - start > 4 && !strncmp(end - 4, ".git", 4))
|
||||
end -= 4;
|
||||
}
|
||||
strip_suffix(start, is_bundle ? ".bundle" : ".git" , &len);
|
||||
|
||||
if (is_bare) {
|
||||
struct strbuf result = STRBUF_INIT;
|
||||
strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
|
||||
dir = strbuf_detach(&result, NULL);
|
||||
} else
|
||||
dir = xstrndup(start, end - start);
|
||||
if (is_bare)
|
||||
dir = xstrfmt("%.*s.git", (int)len, start);
|
||||
else
|
||||
dir = xstrndup(start, len);
|
||||
/*
|
||||
* Replace sequences of 'control' characters and whitespace
|
||||
* with one ascii space, remove leading and trailing spaces.
|
||||
|
@ -851,6 +851,11 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flag & REF_ISBROKEN) {
|
||||
warning("ignoring broken ref %s", refname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*cb->grab_pattern) {
|
||||
const char **pattern;
|
||||
int namelen = strlen(refname);
|
||||
|
@ -75,7 +75,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
|
||||
names[i] = argv[i];
|
||||
if (read_mmfile(mmfs + i, fname))
|
||||
return -1;
|
||||
if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
|
||||
if (mmfs[i].size > MAX_XDIFF_SIZE ||
|
||||
buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
|
||||
return error("Cannot merge binary files: %s",
|
||||
argv[i]);
|
||||
}
|
||||
|
@ -118,7 +118,8 @@ static void show_diff(struct merge_list *entry)
|
||||
if (!dst.ptr)
|
||||
size = 0;
|
||||
dst.size = size;
|
||||
xdi_diff(&src, &dst, &xpp, &xecfg, &ecb);
|
||||
if (xdi_diff(&src, &dst, &xpp, &xecfg, &ecb))
|
||||
die("unable to generate diff");
|
||||
free(src.ptr);
|
||||
free(dst.ptr);
|
||||
}
|
||||
|
@ -29,9 +29,10 @@ static int diff_two(const char *file1, const char *label1,
|
||||
xdemitconf_t xecfg;
|
||||
xdemitcb_t ecb;
|
||||
mmfile_t minus, plus;
|
||||
int ret;
|
||||
|
||||
if (read_mmfile(&minus, file1) || read_mmfile(&plus, file2))
|
||||
return 1;
|
||||
return -1;
|
||||
|
||||
printf("--- a/%s\n+++ b/%s\n", label1, label2);
|
||||
fflush(stdout);
|
||||
@ -40,11 +41,11 @@ static int diff_two(const char *file1, const char *label1,
|
||||
memset(&xecfg, 0, sizeof(xecfg));
|
||||
xecfg.ctxlen = 3;
|
||||
ecb.outf = outf;
|
||||
xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
|
||||
ret = xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
|
||||
|
||||
free(minus.ptr);
|
||||
free(plus.ptr);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_rerere(int argc, const char **argv, const char *prefix)
|
||||
@ -104,7 +105,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
|
||||
for (i = 0; i < merge_rr.nr; i++) {
|
||||
const char *path = merge_rr.items[i].string;
|
||||
const char *name = (const char *)merge_rr.items[i].util;
|
||||
diff_two(rerere_path(name, "preimage"), path, path, path);
|
||||
if (diff_two(rerere_path(name, "preimage"), path, path, path))
|
||||
die("unable to generate diff for %s", name);
|
||||
}
|
||||
else
|
||||
usage_with_options(rerere_usage, options);
|
||||
|
@ -723,7 +723,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
|
||||
if (reflog) {
|
||||
unsigned char sha1[20];
|
||||
char nth_desc[256];
|
||||
char *ref;
|
||||
int base = 0;
|
||||
unsigned int flags = 0;
|
||||
@ -762,6 +761,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
|
||||
for (i = 0; i < reflog; i++) {
|
||||
char *logmsg;
|
||||
char *nth_desc;
|
||||
const char *msg;
|
||||
unsigned long timestamp;
|
||||
int tz;
|
||||
@ -780,8 +780,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
show_date(timestamp, tz, 1),
|
||||
msg);
|
||||
free(logmsg);
|
||||
sprintf(nth_desc, "%s@{%d}", *av, base+i);
|
||||
|
||||
nth_desc = xstrfmt("%s@{%d}", *av, base+i);
|
||||
append_ref(nth_desc, sha1, 1);
|
||||
free(nth_desc);
|
||||
}
|
||||
free(ref);
|
||||
}
|
||||
|
@ -419,8 +419,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
|
||||
state.num_parent = num_parent;
|
||||
state.n = n;
|
||||
|
||||
xdi_diff_outf(&parent_file, result_file, consume_line, &state,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&parent_file, result_file, consume_line, &state,
|
||||
&xpp, &xecfg))
|
||||
die("unable to generate combined diff for %s",
|
||||
sha1_to_hex(parent));
|
||||
free(parent_file.ptr);
|
||||
|
||||
/* Assign line numbers for this parent.
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "url.h"
|
||||
#include "string-list.h"
|
||||
#include "sha1-array.h"
|
||||
#include "transport.h"
|
||||
|
||||
static char *server_capabilities;
|
||||
static const char *parse_feature_value(const char *, const char *, int *);
|
||||
@ -694,6 +695,8 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
else
|
||||
target_host = xstrdup(hostandport);
|
||||
|
||||
transport_check_allowed("git");
|
||||
|
||||
/* These underlying connection commands die() if they
|
||||
* cannot connect.
|
||||
*/
|
||||
@ -727,6 +730,7 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
int putty, tortoiseplink = 0;
|
||||
char *ssh_host = hostandport;
|
||||
const char *port = NULL;
|
||||
transport_check_allowed("ssh");
|
||||
get_host_and_port(&ssh_host, &port);
|
||||
|
||||
if (!port)
|
||||
@ -781,6 +785,7 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
/* remove repo-local variables from the environment */
|
||||
conn->env = local_repo_env;
|
||||
conn->use_shell = 1;
|
||||
transport_check_allowed("file");
|
||||
}
|
||||
argv_array_push(&conn->args, cmd.buf);
|
||||
|
||||
|
@ -1114,7 +1114,7 @@ _git_commit ()
|
||||
|
||||
case "$cur" in
|
||||
--cleanup=*)
|
||||
__gitcomp "default strip verbatim whitespace
|
||||
__gitcomp "default scissors strip verbatim whitespace
|
||||
" "" "${cur##--cleanup=}"
|
||||
return
|
||||
;;
|
||||
|
26
diff.c
26
diff.c
@ -1002,8 +1002,9 @@ static void diff_words_show(struct diff_words_data *diff_words)
|
||||
xpp.flags = 0;
|
||||
/* as only the hunk header will be parsed, we need a 0-context */
|
||||
xecfg.ctxlen = 0;
|
||||
xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
|
||||
&xpp, &xecfg))
|
||||
die("unable to generate word diff");
|
||||
free(minus.ptr);
|
||||
free(plus.ptr);
|
||||
if (diff_words->current_plus != diff_words->plus.text.ptr +
|
||||
@ -2400,8 +2401,9 @@ static void builtin_diff(const char *name_a,
|
||||
xecfg.ctxlen = strtoul(v, NULL, 10);
|
||||
if (o->word_diff)
|
||||
init_diff_words_data(&ecbdata, o, one, two);
|
||||
xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
|
||||
&xpp, &xecfg))
|
||||
die("unable to generate diff for %s", one->path);
|
||||
if (o->word_diff)
|
||||
free_diff_words_data(&ecbdata);
|
||||
if (textconv_one)
|
||||
@ -2478,8 +2480,9 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
|
||||
xpp.flags = o->xdl_opts;
|
||||
xecfg.ctxlen = o->context;
|
||||
xecfg.interhunkctxlen = o->interhunkcontext;
|
||||
xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
|
||||
&xpp, &xecfg))
|
||||
die("unable to generate diffstat for %s", one->path);
|
||||
}
|
||||
|
||||
diff_free_filespec_data(one);
|
||||
@ -2525,8 +2528,9 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
memset(&xecfg, 0, sizeof(xecfg));
|
||||
xecfg.ctxlen = 1; /* at least one context line */
|
||||
xpp.flags = 0;
|
||||
xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
|
||||
&xpp, &xecfg))
|
||||
die("unable to generate checkdiff for %s", one->path);
|
||||
|
||||
if (data.ws_rule & WS_BLANK_AT_EOF) {
|
||||
struct emit_callback ecbdata;
|
||||
@ -4425,8 +4429,10 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
|
||||
xpp.flags = 0;
|
||||
xecfg.ctxlen = 3;
|
||||
xecfg.flags = 0;
|
||||
xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
|
||||
&xpp, &xecfg))
|
||||
return error("unable to generate patch-id diff for %s",
|
||||
p->one->path);
|
||||
}
|
||||
|
||||
git_SHA1_Final(sha1, &ctx);
|
||||
|
@ -62,8 +62,8 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
|
||||
ecbdata.hit = 0;
|
||||
xecfg.ctxlen = o->context;
|
||||
xecfg.interhunkctxlen = o->interhunkcontext;
|
||||
xdi_diff_outf(one, two, diffgrep_consume, &ecbdata,
|
||||
&xpp, &xecfg);
|
||||
if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg))
|
||||
return 0;
|
||||
return ecbdata.hit;
|
||||
}
|
||||
|
||||
|
31
git-am.sh
31
git-am.sh
@ -69,6 +69,8 @@ then
|
||||
cmdline="$cmdline -3"
|
||||
fi
|
||||
|
||||
empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||
|
||||
sq () {
|
||||
git rev-parse --sq-quote "$@"
|
||||
}
|
||||
@ -85,7 +87,7 @@ safe_to_abort () {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! test -s "$dotest/abort-safety"
|
||||
if ! test -f "$dotest/abort-safety"
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
@ -177,7 +179,8 @@ It does not apply to blobs recorded in its index.")"
|
||||
then
|
||||
GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
|
||||
fi
|
||||
git-merge-recursive $orig_tree -- HEAD $his_tree || {
|
||||
our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree)
|
||||
git-merge-recursive $orig_tree -- $our_tree $his_tree || {
|
||||
git rerere $allow_rerere_autoupdate
|
||||
die "$(gettext "Failed to merge in the changes.")"
|
||||
}
|
||||
@ -502,10 +505,11 @@ then
|
||||
;;
|
||||
t,)
|
||||
git rerere clear
|
||||
git read-tree --reset -u HEAD HEAD
|
||||
orig_head=$(cat "$GIT_DIR/ORIG_HEAD")
|
||||
git reset HEAD
|
||||
git update-ref ORIG_HEAD $orig_head
|
||||
head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
|
||||
git read-tree --reset -u $head_tree $head_tree &&
|
||||
index_tree=$(git write-tree) &&
|
||||
git read-tree -m -u $index_tree $head_tree
|
||||
git read-tree $head_tree
|
||||
;;
|
||||
,t)
|
||||
if test -f "$dotest/rebasing"
|
||||
@ -515,8 +519,19 @@ then
|
||||
git rerere clear
|
||||
if safe_to_abort
|
||||
then
|
||||
git read-tree --reset -u HEAD ORIG_HEAD
|
||||
git reset ORIG_HEAD
|
||||
head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
|
||||
git read-tree --reset -u $head_tree $head_tree &&
|
||||
index_tree=$(git write-tree) &&
|
||||
orig_head=$(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) &&
|
||||
git read-tree -m -u $index_tree $orig_head
|
||||
if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1
|
||||
then
|
||||
git reset ORIG_HEAD
|
||||
else
|
||||
git read-tree $empty_tree
|
||||
curr_branch=$(git symbolic-ref HEAD 2>/dev/null) &&
|
||||
git update-ref -d $curr_branch
|
||||
fi
|
||||
fi
|
||||
rm -fr "$dotest"
|
||||
exit ;;
|
||||
|
@ -849,7 +849,11 @@ continue)
|
||||
# do we have anything to commit?
|
||||
if git diff-index --cached --quiet HEAD --
|
||||
then
|
||||
: Nothing to commit -- skip this
|
||||
# Nothing to commit -- skip this commit
|
||||
|
||||
test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
|
||||
rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
|
||||
die "Could not remove CHERRY_PICK_HEAD"
|
||||
else
|
||||
if ! test -f "$author_script"
|
||||
then
|
||||
|
@ -22,6 +22,15 @@ require_work_tree
|
||||
wt_prefix=$(git rev-parse --show-prefix)
|
||||
cd_to_toplevel
|
||||
|
||||
# Restrict ourselves to a vanilla subset of protocols; the URLs
|
||||
# we get are under control of a remote repository, and we do not
|
||||
# want them kicking off arbitrary git-remote-* programs.
|
||||
#
|
||||
# If the user has already specified a set of allowed protocols,
|
||||
# we assume they know what they're doing and use that instead.
|
||||
: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh}
|
||||
export GIT_ALLOW_PROTOCOL
|
||||
|
||||
command=
|
||||
branch=
|
||||
force=
|
||||
|
18
http.c
18
http.c
@ -9,6 +9,7 @@
|
||||
#include "version.h"
|
||||
#include "pkt-line.h"
|
||||
#include "gettext.h"
|
||||
#include "transport.h"
|
||||
|
||||
int active_requests;
|
||||
int http_is_verbose;
|
||||
@ -337,6 +338,7 @@ static void set_curl_keepalive(CURL *c)
|
||||
static CURL *get_curl_handle(void)
|
||||
{
|
||||
CURL *result = curl_easy_init();
|
||||
long allowed_protocols = 0;
|
||||
|
||||
if (!result)
|
||||
die("curl_easy_init failed");
|
||||
@ -384,11 +386,27 @@ static CURL *get_curl_handle(void)
|
||||
}
|
||||
|
||||
curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
|
||||
#if LIBCURL_VERSION_NUM >= 0x071301
|
||||
curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
|
||||
#elif LIBCURL_VERSION_NUM >= 0x071101
|
||||
curl_easy_setopt(result, CURLOPT_POST301, 1);
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (is_transport_allowed("http"))
|
||||
allowed_protocols |= CURLPROTO_HTTP;
|
||||
if (is_transport_allowed("https"))
|
||||
allowed_protocols |= CURLPROTO_HTTPS;
|
||||
if (is_transport_allowed("ftp"))
|
||||
allowed_protocols |= CURLPROTO_FTP;
|
||||
if (is_transport_allowed("ftps"))
|
||||
allowed_protocols |= CURLPROTO_FTPS;
|
||||
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS, allowed_protocols);
|
||||
#else
|
||||
if (transport_restrict_protocols())
|
||||
warning("protocol restrictions not applied to curl redirects because\n"
|
||||
"your curl version is too old (>= 7.19.4)");
|
||||
#endif
|
||||
|
||||
if (getenv("GIT_CURL_VERBOSE"))
|
||||
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
|
||||
|
@ -325,7 +325,7 @@ static int collect_diff_cb(long start_a, long count_a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
|
||||
static int collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
|
||||
{
|
||||
struct collect_diff_cbdata cbdata = {NULL};
|
||||
xpparam_t xpp;
|
||||
@ -340,7 +340,7 @@ static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges
|
||||
xecfg.hunk_func = collect_diff_cb;
|
||||
memset(&ecb, 0, sizeof(ecb));
|
||||
ecb.priv = &cbdata;
|
||||
xdi_diff(parent, target, &xpp, &xecfg, &ecb);
|
||||
return xdi_diff(parent, target, &xpp, &xecfg, &ecb);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1030,7 +1030,8 @@ static int process_diff_filepair(struct rev_info *rev,
|
||||
}
|
||||
|
||||
diff_ranges_init(&diff);
|
||||
collect_diff(&file_parent, &file_target, &diff);
|
||||
if (collect_diff(&file_parent, &file_target, &diff))
|
||||
die("unable to generate diff for %s", pair->one->path);
|
||||
|
||||
/* NEEDSWORK should apply some heuristics to prevent mismatches */
|
||||
free(rg->path);
|
||||
|
@ -88,7 +88,10 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
||||
xmparam_t xmp;
|
||||
assert(opts);
|
||||
|
||||
if (buffer_is_binary(orig->ptr, orig->size) ||
|
||||
if (orig->size > MAX_XDIFF_SIZE ||
|
||||
src1->size > MAX_XDIFF_SIZE ||
|
||||
src2->size > MAX_XDIFF_SIZE ||
|
||||
buffer_is_binary(orig->ptr, orig->size) ||
|
||||
buffer_is_binary(src1->ptr, src1->size) ||
|
||||
buffer_is_binary(src2->ptr, src2->size)) {
|
||||
return ll_binary_merge(drv_unused, result,
|
||||
|
19
notes.c
19
notes.c
@ -362,13 +362,14 @@ static int non_note_cmp(const struct non_note *a, const struct non_note *b)
|
||||
return strcmp(a->path, b->path);
|
||||
}
|
||||
|
||||
static void add_non_note(struct notes_tree *t, const char *path,
|
||||
/* note: takes ownership of path string */
|
||||
static void add_non_note(struct notes_tree *t, char *path,
|
||||
unsigned int mode, const unsigned char *sha1)
|
||||
{
|
||||
struct non_note *p = t->prev_non_note, *n;
|
||||
n = (struct non_note *) xmalloc(sizeof(struct non_note));
|
||||
n->next = NULL;
|
||||
n->path = xstrdup(path);
|
||||
n->path = path;
|
||||
n->mode = mode;
|
||||
hashcpy(n->sha1, sha1);
|
||||
t->prev_non_note = n;
|
||||
@ -482,17 +483,17 @@ handle_non_note:
|
||||
* component.
|
||||
*/
|
||||
{
|
||||
char non_note_path[PATH_MAX];
|
||||
char *p = non_note_path;
|
||||
struct strbuf non_note_path = STRBUF_INIT;
|
||||
const char *q = sha1_to_hex(subtree->key_sha1);
|
||||
int i;
|
||||
for (i = 0; i < prefix_len; i++) {
|
||||
*p++ = *q++;
|
||||
*p++ = *q++;
|
||||
*p++ = '/';
|
||||
strbuf_addch(&non_note_path, *q++);
|
||||
strbuf_addch(&non_note_path, *q++);
|
||||
strbuf_addch(&non_note_path, '/');
|
||||
}
|
||||
strcpy(p, entry.path);
|
||||
add_non_note(t, non_note_path, entry.mode, entry.sha1);
|
||||
strbuf_addstr(&non_note_path, entry.path);
|
||||
add_non_note(t, strbuf_detach(&non_note_path, NULL),
|
||||
entry.mode, entry.sha1);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
29
refs.c
29
refs.c
@ -1374,19 +1374,34 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
|
||||
create_dir_entry(refs, refname.buf,
|
||||
refname.len, 1));
|
||||
} else {
|
||||
int read_ok;
|
||||
|
||||
if (*refs->name) {
|
||||
hashclr(sha1);
|
||||
flag = 0;
|
||||
if (resolve_gitlink_ref(refs->name, refname.buf, sha1) < 0) {
|
||||
hashclr(sha1);
|
||||
flag |= REF_ISBROKEN;
|
||||
}
|
||||
} else if (read_ref_full(refname.buf,
|
||||
RESOLVE_REF_READING,
|
||||
sha1, &flag)) {
|
||||
read_ok = !resolve_gitlink_ref(refs->name,
|
||||
refname.buf, sha1);
|
||||
} else {
|
||||
read_ok = !read_ref_full(refname.buf,
|
||||
RESOLVE_REF_READING,
|
||||
sha1, &flag);
|
||||
}
|
||||
|
||||
if (!read_ok) {
|
||||
hashclr(sha1);
|
||||
flag |= REF_ISBROKEN;
|
||||
} else if (is_null_sha1(sha1)) {
|
||||
/*
|
||||
* It is so astronomically unlikely
|
||||
* that NULL_SHA1 is the SHA-1 of an
|
||||
* actual object that we consider its
|
||||
* appearance in a loose reference
|
||||
* file to be repo corruption
|
||||
* (probably due to a software bug).
|
||||
*/
|
||||
flag |= REF_ISBROKEN;
|
||||
}
|
||||
|
||||
if (check_refname_format(refname.buf,
|
||||
REFNAME_ALLOW_ONELEVEL)) {
|
||||
hashclr(sha1);
|
||||
|
@ -377,15 +377,12 @@ void read_info_alternates(const char * relative_base, int depth)
|
||||
char *map;
|
||||
size_t mapsz;
|
||||
struct stat st;
|
||||
const char alt_file_name[] = "info/alternates";
|
||||
/* Given that relative_base is no longer than PATH_MAX,
|
||||
ensure that "path" has enough space to append "/", the
|
||||
file name, "info/alternates", and a trailing NUL. */
|
||||
char path[PATH_MAX + 1 + sizeof alt_file_name];
|
||||
char *path;
|
||||
int fd;
|
||||
|
||||
sprintf(path, "%s/%s", relative_base, alt_file_name);
|
||||
path = xstrfmt("%s/info/alternates", relative_base);
|
||||
fd = git_open_noatime(path);
|
||||
free(path);
|
||||
if (fd < 0)
|
||||
return;
|
||||
if (fstat(fd, &st) || (st.st_size == 0)) {
|
||||
|
@ -119,6 +119,10 @@ RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301]
|
||||
RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
|
||||
RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301]
|
||||
RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301]
|
||||
RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302]
|
||||
|
||||
RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302]
|
||||
RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302]
|
||||
|
||||
<IfDefine SSL>
|
||||
LoadModule ssl_module modules/mod_ssl.so
|
||||
|
96
t/lib-proto-disable.sh
Normal file
96
t/lib-proto-disable.sh
Normal file
@ -0,0 +1,96 @@
|
||||
# Test routines for checking protocol disabling.
|
||||
|
||||
# test cloning a particular protocol
|
||||
# $1 - description of the protocol
|
||||
# $2 - machine-readable name of the protocol
|
||||
# $3 - the URL to try cloning
|
||||
test_proto () {
|
||||
desc=$1
|
||||
proto=$2
|
||||
url=$3
|
||||
|
||||
test_expect_success "clone $1 (enabled)" '
|
||||
rm -rf tmp.git &&
|
||||
(
|
||||
GIT_ALLOW_PROTOCOL=$proto &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
git clone --bare "$url" tmp.git
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "fetch $1 (enabled)" '
|
||||
(
|
||||
cd tmp.git &&
|
||||
GIT_ALLOW_PROTOCOL=$proto &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
git fetch
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "push $1 (enabled)" '
|
||||
(
|
||||
cd tmp.git &&
|
||||
GIT_ALLOW_PROTOCOL=$proto &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
git push origin HEAD:pushed
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "push $1 (disabled)" '
|
||||
(
|
||||
cd tmp.git &&
|
||||
GIT_ALLOW_PROTOCOL=none &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
test_must_fail git push origin HEAD:pushed
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "fetch $1 (disabled)" '
|
||||
(
|
||||
cd tmp.git &&
|
||||
GIT_ALLOW_PROTOCOL=none &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
test_must_fail git fetch
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "clone $1 (disabled)" '
|
||||
rm -rf tmp.git &&
|
||||
(
|
||||
GIT_ALLOW_PROTOCOL=none &&
|
||||
export GIT_ALLOW_PROTOCOL &&
|
||||
test_must_fail git clone --bare "$url" tmp.git
|
||||
)
|
||||
'
|
||||
}
|
||||
|
||||
# set up an ssh wrapper that will access $host/$repo in the
|
||||
# trash directory, and enable it for subsequent tests.
|
||||
setup_ssh_wrapper () {
|
||||
test_expect_success 'setup ssh wrapper' '
|
||||
write_script ssh-wrapper <<-\EOF &&
|
||||
echo >&2 "ssh: $*"
|
||||
host=$1; shift
|
||||
cd "$TRASH_DIRECTORY/$host" &&
|
||||
eval "$*"
|
||||
EOF
|
||||
GIT_SSH="$PWD/ssh-wrapper" &&
|
||||
export GIT_SSH &&
|
||||
export TRASH_DIRECTORY
|
||||
'
|
||||
}
|
||||
|
||||
# set up a wrapper that can be used with remote-ext to
|
||||
# access repositories in the "remote" directory of trash-dir,
|
||||
# like "ext::fake-remote %S repo.git"
|
||||
setup_ext_wrapper () {
|
||||
test_expect_success 'setup ext wrapper' '
|
||||
write_script fake-remote <<-\EOF &&
|
||||
echo >&2 "fake-remote: $*"
|
||||
cd "$TRASH_DIRECTORY/remote" &&
|
||||
eval "$*"
|
||||
EOF
|
||||
PATH=$TRASH_DIRECTORY:$PATH &&
|
||||
export TRASH_DIRECTORY
|
||||
'
|
||||
}
|
@ -1102,4 +1102,25 @@ test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '
|
||||
test $(git cat-file commit HEAD | sed -ne \$p) = I
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '
|
||||
git checkout -b commit-to-skip &&
|
||||
for double in X 3 1
|
||||
do
|
||||
test_seq 5 | sed "s/$double/&&/" >seq &&
|
||||
git add seq &&
|
||||
test_tick &&
|
||||
git commit -m seq-$double
|
||||
done &&
|
||||
git tag seq-onto &&
|
||||
git reset --hard HEAD~2 &&
|
||||
git cherry-pick seq-onto &&
|
||||
set_fake_editor &&
|
||||
test_must_fail env FAKE_LINES= git rebase -i seq-onto &&
|
||||
test -d .git/rebase-merge &&
|
||||
git rebase --continue &&
|
||||
git diff --exit-code seq-onto &&
|
||||
test ! -d .git/rebase-merge &&
|
||||
test ! -f .git/CHERRY_PICK_HEAD
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -14,6 +14,7 @@ test_expect_success setup '
|
||||
git add file-1 file-2 &&
|
||||
git commit -m initial &&
|
||||
git tag initial &&
|
||||
git format-patch --stdout --root initial >initial.patch &&
|
||||
for i in 2 3 4 5 6
|
||||
do
|
||||
echo $i >>file-1 &&
|
||||
@ -63,6 +64,28 @@ do
|
||||
|
||||
done
|
||||
|
||||
test_expect_success 'am -3 --skip removes otherfile-4' '
|
||||
git reset --hard initial &&
|
||||
test_must_fail git am -3 0003-*.patch &&
|
||||
test 3 -eq $(git ls-files -u | wc -l) &&
|
||||
test 4 = "$(cat otherfile-4)" &&
|
||||
git am --skip &&
|
||||
test_cmp_rev initial HEAD &&
|
||||
test -z "$(git ls-files -u)" &&
|
||||
test_path_is_missing otherfile-4
|
||||
'
|
||||
|
||||
test_expect_success 'am -3 --abort removes otherfile-4' '
|
||||
git reset --hard initial &&
|
||||
test_must_fail git am -3 0003-*.patch &&
|
||||
test 3 -eq $(git ls-files -u | wc -l) &&
|
||||
test 4 = "$(cat otherfile-4)" &&
|
||||
git am --abort &&
|
||||
test_cmp_rev initial HEAD &&
|
||||
test -z $(git ls-files -u) &&
|
||||
test_path_is_missing otherfile-4
|
||||
'
|
||||
|
||||
test_expect_success 'am --abort will keep the local commits intact' '
|
||||
test_must_fail git am 0004-*.patch &&
|
||||
test_commit unrelated &&
|
||||
@ -72,4 +95,62 @@ test_expect_success 'am --abort will keep the local commits intact' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'am -3 stops on conflict on unborn branch' '
|
||||
git checkout -f --orphan orphan &&
|
||||
git reset &&
|
||||
rm -f otherfile-4 &&
|
||||
test_must_fail git am -3 0003-*.patch &&
|
||||
test 2 -eq $(git ls-files -u | wc -l) &&
|
||||
test 4 = "$(cat otherfile-4)"
|
||||
'
|
||||
|
||||
test_expect_success 'am -3 --skip clears index on unborn branch' '
|
||||
test_path_is_dir .git/rebase-apply &&
|
||||
echo tmpfile >tmpfile &&
|
||||
git add tmpfile &&
|
||||
git am --skip &&
|
||||
test -z "$(git ls-files)" &&
|
||||
test_path_is_missing otherfile-4 &&
|
||||
test_path_is_missing tmpfile
|
||||
'
|
||||
|
||||
test_expect_success 'am -3 --abort removes otherfile-4 on unborn branch' '
|
||||
git checkout -f --orphan orphan &&
|
||||
git reset &&
|
||||
rm -f otherfile-4 file-1 &&
|
||||
test_must_fail git am -3 0003-*.patch &&
|
||||
test 2 -eq $(git ls-files -u | wc -l) &&
|
||||
test 4 = "$(cat otherfile-4)" &&
|
||||
git am --abort &&
|
||||
test -z "$(git ls-files -u)" &&
|
||||
test_path_is_missing otherfile-4
|
||||
'
|
||||
|
||||
test_expect_success 'am -3 --abort on unborn branch removes applied commits' '
|
||||
git checkout -f --orphan orphan &&
|
||||
git reset &&
|
||||
rm -f otherfile-4 otherfile-2 file-1 file-2 &&
|
||||
test_must_fail git am -3 initial.patch 0003-*.patch &&
|
||||
test 3 -eq $(git ls-files -u | wc -l) &&
|
||||
test 4 = "$(cat otherfile-4)" &&
|
||||
git am --abort &&
|
||||
test -z "$(git ls-files -u)" &&
|
||||
test_path_is_missing otherfile-4 &&
|
||||
test_path_is_missing file-1 &&
|
||||
test_path_is_missing file-2 &&
|
||||
test 0 -eq $(git log --oneline 2>/dev/null | wc -l) &&
|
||||
test refs/heads/orphan = "$(git symbolic-ref HEAD)"
|
||||
'
|
||||
|
||||
test_expect_success 'am --abort on unborn branch will keep local commits intact' '
|
||||
git checkout -f --orphan orphan &&
|
||||
git reset &&
|
||||
test_must_fail git am 0004-*.patch &&
|
||||
test_commit unrelated2 &&
|
||||
git rev-parse HEAD >expect &&
|
||||
git am --abort &&
|
||||
git rev-parse HEAD >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
14
t/t5810-proto-disable-local.sh
Executable file
14
t/t5810-proto-disable-local.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test disabling of local paths in clone/fetch'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-proto-disable.sh"
|
||||
|
||||
test_expect_success 'setup repository to clone' '
|
||||
test_commit one
|
||||
'
|
||||
|
||||
test_proto "file://" file "file://$PWD"
|
||||
test_proto "path" file .
|
||||
|
||||
test_done
|
20
t/t5811-proto-disable-git.sh
Executable file
20
t/t5811-proto-disable-git.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test disabling of git-over-tcp in clone/fetch'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-proto-disable.sh"
|
||||
. "$TEST_DIRECTORY/lib-git-daemon.sh"
|
||||
start_git_daemon
|
||||
|
||||
test_expect_success 'create git-accessible repo' '
|
||||
bare="$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
test_commit one &&
|
||||
git --bare init "$bare" &&
|
||||
git push "$bare" HEAD &&
|
||||
>"$bare/git-daemon-export-ok" &&
|
||||
git -C "$bare" config daemon.receivepack true
|
||||
'
|
||||
|
||||
test_proto "git://" git "$GIT_DAEMON_URL/repo.git"
|
||||
|
||||
test_done
|
33
t/t5812-proto-disable-http.sh
Executable file
33
t/t5812-proto-disable-http.sh
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test disabling of git-over-http in clone/fetch'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-proto-disable.sh"
|
||||
. "$TEST_DIRECTORY/lib-httpd.sh"
|
||||
start_httpd
|
||||
|
||||
test_expect_success 'create git-accessible repo' '
|
||||
bare="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
test_commit one &&
|
||||
git --bare init "$bare" &&
|
||||
git push "$bare" HEAD &&
|
||||
git -C "$bare" config http.receivepack true
|
||||
'
|
||||
|
||||
test_proto "smart http" http "$HTTPD_URL/smart/repo.git"
|
||||
|
||||
test_expect_success 'curl redirects respect whitelist' '
|
||||
test_must_fail env GIT_ALLOW_PROTOCOL=http:https \
|
||||
git clone "$HTTPD_URL/ftp-redir/repo.git" 2>stderr &&
|
||||
{
|
||||
test_i18ngrep "ftp.*disabled" stderr ||
|
||||
test_i18ngrep "your curl version is too old"
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'curl limits redirects' '
|
||||
test_must_fail git clone "$HTTPD_URL/loop-redir/smart/repo.git"
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
test_done
|
20
t/t5813-proto-disable-ssh.sh
Executable file
20
t/t5813-proto-disable-ssh.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test disabling of git-over-ssh in clone/fetch'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-proto-disable.sh"
|
||||
|
||||
setup_ssh_wrapper
|
||||
|
||||
test_expect_success 'setup repository to clone' '
|
||||
test_commit one &&
|
||||
mkdir remote &&
|
||||
git init --bare remote/repo.git &&
|
||||
git push remote/repo.git HEAD
|
||||
'
|
||||
|
||||
test_proto "host:path" ssh "remote:repo.git"
|
||||
test_proto "ssh://" ssh "ssh://remote/$PWD/remote/repo.git"
|
||||
test_proto "git+ssh://" ssh "git+ssh://remote/$PWD/remote/repo.git"
|
||||
|
||||
test_done
|
18
t/t5814-proto-disable-ext.sh
Executable file
18
t/t5814-proto-disable-ext.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test disabling of remote-helper paths in clone/fetch'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-proto-disable.sh"
|
||||
|
||||
setup_ext_wrapper
|
||||
|
||||
test_expect_success 'setup repository to clone' '
|
||||
test_commit one &&
|
||||
mkdir remote &&
|
||||
git init --bare remote/repo.git &&
|
||||
git push remote/repo.git HEAD
|
||||
'
|
||||
|
||||
test_proto "remote-helper" ext "ext::fake-remote %S repo.git"
|
||||
|
||||
test_done
|
43
t/t5815-submodule-protos.sh
Executable file
43
t/t5815-submodule-protos.sh
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test protocol whitelisting with submodules'
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY"/lib-proto-disable.sh
|
||||
|
||||
setup_ext_wrapper
|
||||
setup_ssh_wrapper
|
||||
|
||||
test_expect_success 'setup repository with submodules' '
|
||||
mkdir remote &&
|
||||
git init remote/repo.git &&
|
||||
(cd remote/repo.git && test_commit one) &&
|
||||
# submodule-add should probably trust what we feed it on the cmdline,
|
||||
# but its implementation is overly conservative.
|
||||
GIT_ALLOW_PROTOCOL=ssh git submodule add remote:repo.git ssh-module &&
|
||||
GIT_ALLOW_PROTOCOL=ext git submodule add "ext::fake-remote %S repo.git" ext-module &&
|
||||
git commit -m "add submodules"
|
||||
'
|
||||
|
||||
test_expect_success 'clone with recurse-submodules fails' '
|
||||
test_must_fail git clone --recurse-submodules . dst
|
||||
'
|
||||
|
||||
test_expect_success 'setup individual updates' '
|
||||
rm -rf dst &&
|
||||
git clone . dst &&
|
||||
git -C dst submodule init
|
||||
'
|
||||
|
||||
test_expect_success 'update of ssh allowed' '
|
||||
git -C dst submodule update ssh-module
|
||||
'
|
||||
|
||||
test_expect_success 'update of ext not allowed' '
|
||||
test_must_fail git -C dst submodule update ext-module
|
||||
'
|
||||
|
||||
test_expect_success 'user can override whitelist' '
|
||||
GIT_ALLOW_PROTOCOL=ext git -C dst submodule update ext-module
|
||||
'
|
||||
|
||||
test_done
|
56
t/t6301-for-each-ref-errors.sh
Executable file
56
t/t6301-for-each-ref-errors.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='for-each-ref errors for broken refs'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
ZEROS=$_z40
|
||||
MISSING=abababababababababababababababababababab
|
||||
|
||||
test_expect_success setup '
|
||||
git commit --allow-empty -m "Initial" &&
|
||||
git tag testtag &&
|
||||
git for-each-ref >full-list &&
|
||||
git for-each-ref --format="%(objectname) %(refname)" >brief-list
|
||||
'
|
||||
|
||||
test_expect_success 'Broken refs are reported correctly' '
|
||||
r=refs/heads/bogus &&
|
||||
: >.git/$r &&
|
||||
test_when_finished "rm -f .git/$r" &&
|
||||
echo "warning: ignoring broken ref $r" >broken-err &&
|
||||
git for-each-ref >out 2>err &&
|
||||
test_cmp full-list out &&
|
||||
test_cmp broken-err err
|
||||
'
|
||||
|
||||
test_expect_success 'NULL_SHA1 refs are reported correctly' '
|
||||
r=refs/heads/zeros &&
|
||||
echo $ZEROS >.git/$r &&
|
||||
test_when_finished "rm -f .git/$r" &&
|
||||
echo "warning: ignoring broken ref $r" >zeros-err &&
|
||||
git for-each-ref >out 2>err &&
|
||||
test_cmp full-list out &&
|
||||
test_cmp zeros-err err &&
|
||||
git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err &&
|
||||
test_cmp brief-list brief-out &&
|
||||
test_cmp zeros-err brief-err
|
||||
'
|
||||
|
||||
test_expect_success 'Missing objects are reported correctly' '
|
||||
r=refs/heads/missing &&
|
||||
echo $MISSING >.git/$r &&
|
||||
test_when_finished "rm -f .git/$r" &&
|
||||
echo "fatal: missing object $MISSING for $r" >missing-err &&
|
||||
test_must_fail git for-each-ref 2>err &&
|
||||
test_cmp missing-err err &&
|
||||
(
|
||||
cat brief-list &&
|
||||
echo "$MISSING $r"
|
||||
) | sort -k 2 >missing-brief-expected &&
|
||||
git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err &&
|
||||
test_cmp missing-brief-expected brief-out &&
|
||||
test_must_be_empty brief-err
|
||||
'
|
||||
|
||||
test_done
|
@ -229,14 +229,36 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '
|
||||
cat >text <<EOF &&
|
||||
|
||||
# to be kept
|
||||
|
||||
# ------------------------ >8 ------------------------
|
||||
# to be kept, too
|
||||
# ------------------------ >8 ------------------------
|
||||
to be removed
|
||||
# ------------------------ >8 ------------------------
|
||||
to be removed, too
|
||||
EOF
|
||||
|
||||
cat >expect <<EOF &&
|
||||
# to be kept
|
||||
|
||||
# ------------------------ >8 ------------------------
|
||||
# to be kept, too
|
||||
EOF
|
||||
echo "# to be kept" >expect &&
|
||||
git commit --cleanup=scissors -e -F text -a &&
|
||||
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on first line)' '
|
||||
|
||||
echo >>negative &&
|
||||
cat >text <<EOF &&
|
||||
# ------------------------ >8 ------------------------
|
||||
to be removed
|
||||
EOF
|
||||
git commit --cleanup=scissors -e -F text -a --allow-empty-message &&
|
||||
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
|
||||
test_must_be_empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'cleanup commit messages (strip option,-F)' '
|
||||
|
@ -1039,6 +1039,8 @@ int transport_helper_init(struct transport *transport, const char *name)
|
||||
struct helper_data *data = xcalloc(1, sizeof(*data));
|
||||
data->name = name;
|
||||
|
||||
transport_check_allowed(name);
|
||||
|
||||
if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
|
||||
debug = 1;
|
||||
|
||||
|
43
transport.c
43
transport.c
@ -914,6 +914,42 @@ static int external_specification_len(const char *url)
|
||||
return strchr(url, ':') - url;
|
||||
}
|
||||
|
||||
static const struct string_list *protocol_whitelist(void)
|
||||
{
|
||||
static int enabled = -1;
|
||||
static struct string_list allowed = STRING_LIST_INIT_DUP;
|
||||
|
||||
if (enabled < 0) {
|
||||
const char *v = getenv("GIT_ALLOW_PROTOCOL");
|
||||
if (v) {
|
||||
string_list_split(&allowed, v, ':', -1);
|
||||
string_list_sort(&allowed);
|
||||
enabled = 1;
|
||||
} else {
|
||||
enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return enabled ? &allowed : NULL;
|
||||
}
|
||||
|
||||
int is_transport_allowed(const char *type)
|
||||
{
|
||||
const struct string_list *allowed = protocol_whitelist();
|
||||
return !allowed || string_list_has_string(allowed, type);
|
||||
}
|
||||
|
||||
void transport_check_allowed(const char *type)
|
||||
{
|
||||
if (!is_transport_allowed(type))
|
||||
die("transport '%s' not allowed", type);
|
||||
}
|
||||
|
||||
int transport_restrict_protocols(void)
|
||||
{
|
||||
return !!protocol_whitelist();
|
||||
}
|
||||
|
||||
struct transport *transport_get(struct remote *remote, const char *url)
|
||||
{
|
||||
const char *helper;
|
||||
@ -945,12 +981,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
||||
if (helper) {
|
||||
transport_helper_init(ret, helper);
|
||||
} else if (starts_with(url, "rsync:")) {
|
||||
transport_check_allowed("rsync");
|
||||
ret->get_refs_list = get_refs_via_rsync;
|
||||
ret->fetch = fetch_objs_via_rsync;
|
||||
ret->push = rsync_transport_push;
|
||||
ret->smart_options = NULL;
|
||||
} else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
|
||||
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
|
||||
transport_check_allowed("file");
|
||||
ret->data = data;
|
||||
ret->get_refs_list = get_refs_from_bundle;
|
||||
ret->fetch = fetch_refs_from_bundle;
|
||||
@ -962,7 +1000,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
||||
|| starts_with(url, "ssh://")
|
||||
|| starts_with(url, "git+ssh://")
|
||||
|| starts_with(url, "ssh+git://")) {
|
||||
/* These are builtin smart transports. */
|
||||
/*
|
||||
* These are builtin smart transports; "allowed" transports
|
||||
* will be checked individually in git_connect.
|
||||
*/
|
||||
struct git_transport_data *data = xcalloc(1, sizeof(*data));
|
||||
ret->data = data;
|
||||
ret->set_option = NULL;
|
||||
|
18
transport.h
18
transport.h
@ -133,6 +133,24 @@ struct transport {
|
||||
/* Returns a transport suitable for the url */
|
||||
struct transport *transport_get(struct remote *, const char *);
|
||||
|
||||
/*
|
||||
* Check whether a transport is allowed by the environment. Type should
|
||||
* generally be the URL scheme, as described in Documentation/git.txt
|
||||
*/
|
||||
int is_transport_allowed(const char *type);
|
||||
|
||||
/*
|
||||
* Check whether a transport is allowed by the environment,
|
||||
* and die otherwise.
|
||||
*/
|
||||
void transport_check_allowed(const char *type);
|
||||
|
||||
/*
|
||||
* Returns true if the user has attempted to turn on protocol
|
||||
* restrictions at all.
|
||||
*/
|
||||
int transport_restrict_protocols(void);
|
||||
|
||||
/* Transport options which apply to git:// and scp-style URLs */
|
||||
|
||||
/* The program to use on the remote side to send a pack */
|
||||
|
@ -1434,15 +1434,18 @@ static int verify_absent_1(const struct cache_entry *ce,
|
||||
if (!len)
|
||||
return 0;
|
||||
else if (len > 0) {
|
||||
char path[PATH_MAX + 1];
|
||||
memcpy(path, ce->name, len);
|
||||
path[len] = 0;
|
||||
if (lstat(path, &st))
|
||||
return error("cannot stat '%s': %s", path,
|
||||
strerror(errno));
|
||||
char *path;
|
||||
int ret;
|
||||
|
||||
return check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st,
|
||||
error_type, o);
|
||||
path = xmemdupz(ce->name, len);
|
||||
if (lstat(path, &st))
|
||||
ret = error("cannot stat '%s': %s", path,
|
||||
strerror(errno));
|
||||
else
|
||||
ret = check_ok_to_remove(path, len, DT_UNKNOWN, NULL,
|
||||
&st, error_type, o);
|
||||
free(path);
|
||||
return ret;
|
||||
} else if (lstat(ce->name, &st)) {
|
||||
if (errno != ENOENT)
|
||||
return error("cannot stat '%s': %s", ce->name,
|
||||
|
@ -823,10 +823,11 @@ void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
|
||||
const char *p;
|
||||
struct strbuf pattern = STRBUF_INIT;
|
||||
|
||||
strbuf_addf(&pattern, "%c %s", comment_line_char, cut_line);
|
||||
p = strstr(buf->buf, pattern.buf);
|
||||
if (p && (p == buf->buf || p[-1] == '\n'))
|
||||
strbuf_setlen(buf, p - buf->buf);
|
||||
strbuf_addf(&pattern, "\n%c %s", comment_line_char, cut_line);
|
||||
if (starts_with(buf->buf, pattern.buf + 1))
|
||||
strbuf_setlen(buf, 0);
|
||||
else if ((p = strstr(buf->buf, pattern.buf)))
|
||||
strbuf_setlen(buf, p - buf->buf + 1);
|
||||
strbuf_release(&pattern);
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,9 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
|
||||
mmfile_t a = *mf1;
|
||||
mmfile_t b = *mf2;
|
||||
|
||||
if (mf1->size > MAX_XDIFF_SIZE || mf2->size > MAX_XDIFF_SIZE)
|
||||
return -1;
|
||||
|
||||
trim_common_tail(&a, &b, xecfg->ctxlen);
|
||||
|
||||
return xdl_diff(&a, &b, xpp, xecfg, xecb);
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
#include "xdiff/xdiff.h"
|
||||
|
||||
/*
|
||||
* xdiff isn't equipped to handle content over a gigabyte;
|
||||
* we make the cutoff 1GB - 1MB to give some breathing
|
||||
* room for constant-sized additions (e.g., merge markers)
|
||||
*/
|
||||
#define MAX_XDIFF_SIZE (1024UL * 1024 * 1023)
|
||||
|
||||
typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long);
|
||||
|
||||
int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
|
||||
|
Reference in New Issue
Block a user