mirror of
https://github.com/git/git.git
synced 2026-03-14 10:53:25 +01:00
Merge branch 'master' into next
* master: gitweb: export options gitweb: do not use 'No such directory' error message git-tar-tree: devolve git-tar-tree into a wrapper for git-archive gitweb: fix uninitialized variable warning. gitweb: more support for PATH_INFO based URLs apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches t1400: make test debuggable.
This commit is contained in:
4
Makefile
4
Makefile
@@ -132,6 +132,8 @@ GITWEB_CONFIG = gitweb_config.perl
|
||||
GITWEB_HOME_LINK_STR = projects
|
||||
GITWEB_SITENAME =
|
||||
GITWEB_PROJECTROOT = /pub/git
|
||||
GITWEB_EXPORT_OK =
|
||||
GITWEB_STRICT_EXPORT =
|
||||
GITWEB_BASE_URL =
|
||||
GITWEB_LIST =
|
||||
GITWEB_HOMETEXT = indextext.html
|
||||
@@ -676,6 +678,8 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
|
||||
-e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
|
||||
-e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
|
||||
-e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
|
||||
-e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
|
||||
-e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
|
||||
-e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
|
||||
-e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
|
||||
-e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
|
||||
|
||||
112
builtin-apply.c
112
builtin-apply.c
@@ -27,6 +27,7 @@ static const char *prefix;
|
||||
static int prefix_length = -1;
|
||||
static int newfd = -1;
|
||||
|
||||
static int unidiff_zero;
|
||||
static int p_value = 1;
|
||||
static int check_index;
|
||||
static int write_index;
|
||||
@@ -854,11 +855,10 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a unified diff. Note that this really needs
|
||||
* to parse each fragment separately, since the only
|
||||
* way to know the difference between a "---" that is
|
||||
* part of a patch, and a "---" that starts the next
|
||||
* patch is to look at the line counts..
|
||||
* Parse a unified diff. Note that this really needs to parse each
|
||||
* fragment separately, since the only way to know the difference
|
||||
* between a "---" that is part of a patch, and a "---" that starts
|
||||
* the next patch is to look at the line counts..
|
||||
*/
|
||||
static int parse_fragment(char *line, unsigned long size, struct patch *patch, struct fragment *fragment)
|
||||
{
|
||||
@@ -875,31 +875,14 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
|
||||
leading = 0;
|
||||
trailing = 0;
|
||||
|
||||
if (patch->is_new < 0) {
|
||||
patch->is_new = !oldlines;
|
||||
if (!oldlines)
|
||||
patch->old_name = NULL;
|
||||
}
|
||||
if (patch->is_delete < 0) {
|
||||
patch->is_delete = !newlines;
|
||||
if (!newlines)
|
||||
patch->new_name = NULL;
|
||||
}
|
||||
|
||||
if (patch->is_new && oldlines)
|
||||
return error("new file depends on old contents");
|
||||
if (patch->is_delete != !newlines) {
|
||||
if (newlines)
|
||||
return error("deleted file still has contents");
|
||||
fprintf(stderr, "** warning: file %s becomes empty but is not deleted\n", patch->new_name);
|
||||
}
|
||||
|
||||
/* Parse the thing.. */
|
||||
line += len;
|
||||
size -= len;
|
||||
linenr++;
|
||||
added = deleted = 0;
|
||||
for (offset = len; size > 0; offset += len, size -= len, line += len, linenr++) {
|
||||
for (offset = len;
|
||||
0 < size;
|
||||
offset += len, size -= len, line += len, linenr++) {
|
||||
if (!oldlines && !newlines)
|
||||
break;
|
||||
len = linelen(line, size);
|
||||
@@ -972,12 +955,18 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
|
||||
|
||||
patch->lines_added += added;
|
||||
patch->lines_deleted += deleted;
|
||||
|
||||
if (0 < patch->is_new && oldlines)
|
||||
return error("new file depends on old contents");
|
||||
if (0 < patch->is_delete && newlines)
|
||||
return error("deleted file still has contents");
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int parse_single_patch(char *line, unsigned long size, struct patch *patch)
|
||||
{
|
||||
unsigned long offset = 0;
|
||||
unsigned long oldlines = 0, newlines = 0, context = 0;
|
||||
struct fragment **fragp = &patch->fragments;
|
||||
|
||||
while (size > 4 && !memcmp(line, "@@ -", 4)) {
|
||||
@@ -988,9 +977,11 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
|
||||
len = parse_fragment(line, size, patch, fragment);
|
||||
if (len <= 0)
|
||||
die("corrupt patch at line %d", linenr);
|
||||
|
||||
fragment->patch = line;
|
||||
fragment->size = len;
|
||||
oldlines += fragment->oldlines;
|
||||
newlines += fragment->newlines;
|
||||
context += fragment->leading + fragment->trailing;
|
||||
|
||||
*fragp = fragment;
|
||||
fragp = &fragment->next;
|
||||
@@ -999,6 +990,46 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
|
||||
line += len;
|
||||
size -= len;
|
||||
}
|
||||
|
||||
/*
|
||||
* If something was removed (i.e. we have old-lines) it cannot
|
||||
* be creation, and if something was added it cannot be
|
||||
* deletion. However, the reverse is not true; --unified=0
|
||||
* patches that only add are not necessarily creation even
|
||||
* though they do not have any old lines, and ones that only
|
||||
* delete are not necessarily deletion.
|
||||
*
|
||||
* Unfortunately, a real creation/deletion patch do _not_ have
|
||||
* any context line by definition, so we cannot safely tell it
|
||||
* apart with --unified=0 insanity. At least if the patch has
|
||||
* more than one hunk it is not creation or deletion.
|
||||
*/
|
||||
if (patch->is_new < 0 &&
|
||||
(oldlines || (patch->fragments && patch->fragments->next)))
|
||||
patch->is_new = 0;
|
||||
if (patch->is_delete < 0 &&
|
||||
(newlines || (patch->fragments && patch->fragments->next)))
|
||||
patch->is_delete = 0;
|
||||
if (!unidiff_zero || context) {
|
||||
/* If the user says the patch is not generated with
|
||||
* --unified=0, or if we have seen context lines,
|
||||
* then not having oldlines means the patch is creation,
|
||||
* and not having newlines means the patch is deletion.
|
||||
*/
|
||||
if (patch->is_new < 0 && !oldlines)
|
||||
patch->is_new = 1;
|
||||
if (patch->is_delete < 0 && !newlines)
|
||||
patch->is_delete = 1;
|
||||
}
|
||||
|
||||
if (0 < patch->is_new && oldlines)
|
||||
die("new file %s depends on old contents", patch->new_name);
|
||||
if (0 < patch->is_delete && newlines)
|
||||
die("deleted file %s still has contents", patch->old_name);
|
||||
if (!patch->is_delete && !newlines && context)
|
||||
fprintf(stderr, "** warning: file %s becomes empty but "
|
||||
"is not deleted\n", patch->new_name);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
@@ -1556,9 +1587,19 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
|
||||
/*
|
||||
* If we don't have any leading/trailing data in the patch,
|
||||
* we want it to match at the beginning/end of the file.
|
||||
*
|
||||
* But that would break if the patch is generated with
|
||||
* --unified=0; sane people wouldn't do that to cause us
|
||||
* trouble, but we try to please not so sane ones as well.
|
||||
*/
|
||||
match_beginning = !leading && (frag->oldpos == 1);
|
||||
match_end = !trailing;
|
||||
if (unidiff_zero) {
|
||||
match_beginning = (!leading && !frag->oldpos);
|
||||
match_end = 0;
|
||||
}
|
||||
else {
|
||||
match_beginning = !leading && (frag->oldpos == 1);
|
||||
match_end = !trailing;
|
||||
}
|
||||
|
||||
lines = 0;
|
||||
pos = frag->newpos;
|
||||
@@ -1804,7 +1845,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
|
||||
patch->result = desc.buffer;
|
||||
patch->resultsize = desc.size;
|
||||
|
||||
if (patch->is_delete && patch->resultsize)
|
||||
if (0 < patch->is_delete && patch->resultsize)
|
||||
return error("removal patch leaves file contents");
|
||||
|
||||
return 0;
|
||||
@@ -1876,7 +1917,7 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
|
||||
old_name, st_mode, patch->old_mode);
|
||||
}
|
||||
|
||||
if (new_name && prev_patch && prev_patch->is_delete &&
|
||||
if (new_name && prev_patch && 0 < prev_patch->is_delete &&
|
||||
!strcmp(prev_patch->old_name, new_name))
|
||||
/* A type-change diff is always split into a patch to
|
||||
* delete old, immediately followed by a patch to
|
||||
@@ -1889,7 +1930,8 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
|
||||
else
|
||||
ok_if_exists = 0;
|
||||
|
||||
if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
|
||||
if (new_name &&
|
||||
((0 < patch->is_new) | (0 < patch->is_rename) | patch->is_copy)) {
|
||||
if (check_index &&
|
||||
cache_name_pos(new_name, strlen(new_name)) >= 0 &&
|
||||
!ok_if_exists)
|
||||
@@ -1906,7 +1948,7 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
|
||||
return error("%s: %s", new_name, strerror(errno));
|
||||
}
|
||||
if (!patch->new_mode) {
|
||||
if (patch->is_new)
|
||||
if (0 < patch->is_new)
|
||||
patch->new_mode = S_IFREG | 0644;
|
||||
else
|
||||
patch->new_mode = patch->old_mode;
|
||||
@@ -1957,7 +1999,7 @@ static void show_index_list(struct patch *list)
|
||||
const char *name;
|
||||
|
||||
name = patch->old_name ? patch->old_name : patch->new_name;
|
||||
if (patch->is_new)
|
||||
if (0 < patch->is_new)
|
||||
sha1_ptr = null_sha1;
|
||||
else if (get_sha1(patch->old_sha1_prefix, sha1))
|
||||
die("sha1 information is lacking or useless (%s).",
|
||||
@@ -2543,6 +2585,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
|
||||
apply_in_reverse = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--unidiff-zero")) {
|
||||
unidiff_zero = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--reject")) {
|
||||
apply = apply_with_reject = apply_verbosely = 1;
|
||||
continue;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
#include <time.h>
|
||||
#include "cache.h"
|
||||
#include "tree-walk.h"
|
||||
#include "commit.h"
|
||||
#include "strbuf.h"
|
||||
#include "tar.h"
|
||||
@@ -248,37 +247,6 @@ static void write_global_extended_header(const unsigned char *sha1)
|
||||
free(ext_header.buf);
|
||||
}
|
||||
|
||||
static void traverse_tree(struct tree_desc *tree, struct strbuf *path)
|
||||
{
|
||||
int pathlen = path->len;
|
||||
struct name_entry entry;
|
||||
|
||||
while (tree_entry(tree, &entry)) {
|
||||
void *eltbuf;
|
||||
char elttype[20];
|
||||
unsigned long eltsize;
|
||||
|
||||
eltbuf = read_sha1_file(entry.sha1, elttype, &eltsize);
|
||||
if (!eltbuf)
|
||||
die("cannot read %s", sha1_to_hex(entry.sha1));
|
||||
|
||||
path->len = pathlen;
|
||||
strbuf_append_string(path, entry.path);
|
||||
if (S_ISDIR(entry.mode))
|
||||
strbuf_append_string(path, "/");
|
||||
|
||||
write_entry(entry.sha1, path, entry.mode, eltbuf, eltsize);
|
||||
|
||||
if (S_ISDIR(entry.mode)) {
|
||||
struct tree_desc subtree;
|
||||
subtree.buf = eltbuf;
|
||||
subtree.size = eltsize;
|
||||
traverse_tree(&subtree, path);
|
||||
}
|
||||
free(eltbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static int git_tar_config(const char *var, const char *value)
|
||||
{
|
||||
if (!strcmp(var, "tar.umask")) {
|
||||
@@ -295,51 +263,29 @@ static int git_tar_config(const char *var, const char *value)
|
||||
|
||||
static int generate_tar(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
unsigned char sha1[20], tree_sha1[20];
|
||||
struct commit *commit;
|
||||
struct tree_desc tree;
|
||||
struct strbuf current_path;
|
||||
void *buffer;
|
||||
|
||||
current_path.buf = xmalloc(PATH_MAX);
|
||||
current_path.alloc = PATH_MAX;
|
||||
current_path.len = current_path.eof = 0;
|
||||
struct archiver_args args;
|
||||
int result;
|
||||
char *base = NULL;
|
||||
|
||||
git_config(git_tar_config);
|
||||
|
||||
switch (argc) {
|
||||
case 3:
|
||||
strbuf_append_string(¤t_path, argv[2]);
|
||||
strbuf_append_string(¤t_path, "/");
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
if (get_sha1(argv[1], sha1))
|
||||
die("Not a valid object name %s", argv[1]);
|
||||
break;
|
||||
default:
|
||||
memset(&args, 0, sizeof(args));
|
||||
if (argc != 2 && argc != 3)
|
||||
usage(tar_tree_usage);
|
||||
if (argc == 3) {
|
||||
int baselen = strlen(argv[2]);
|
||||
base = xmalloc(baselen + 2);
|
||||
memcpy(base, argv[2], baselen);
|
||||
base[baselen] = '/';
|
||||
base[baselen + 1] = '\0';
|
||||
}
|
||||
args.base = base;
|
||||
parse_treeish_arg(argv + 1, &args, NULL);
|
||||
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (commit) {
|
||||
write_global_extended_header(commit->object.sha1);
|
||||
archive_time = commit->date;
|
||||
} else
|
||||
archive_time = time(NULL);
|
||||
result = write_tar_archive(&args);
|
||||
free(base);
|
||||
|
||||
tree.buf = buffer = read_object_with_reference(sha1, tree_type,
|
||||
&tree.size, tree_sha1);
|
||||
if (!tree.buf)
|
||||
die("not a reference to a tag, commit or tree object: %s",
|
||||
sha1_to_hex(sha1));
|
||||
|
||||
if (current_path.len > 0)
|
||||
write_entry(tree_sha1, ¤t_path, 040777, NULL, 0);
|
||||
traverse_tree(&tree, ¤t_path);
|
||||
write_trailer();
|
||||
free(buffer);
|
||||
free(current_path.buf);
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int write_tar_entry(const unsigned char *sha1,
|
||||
@@ -383,7 +329,7 @@ static int write_tar_entry(const unsigned char *sha1,
|
||||
|
||||
int write_tar_archive(struct archiver_args *args)
|
||||
{
|
||||
int plen = strlen(args->base);
|
||||
int plen = args->base ? strlen(args->base) : 0;
|
||||
|
||||
git_config(git_tar_config);
|
||||
|
||||
|
||||
@@ -54,6 +54,13 @@ our $favicon = "++GITWEB_FAVICON++";
|
||||
# source of projects list
|
||||
our $projects_list = "++GITWEB_LIST++";
|
||||
|
||||
# show repository only if this file exists
|
||||
# (only effective if this variable evaluates to true)
|
||||
our $export_ok = "++GITWEB_EXPORT_OK++";
|
||||
|
||||
# only allow viewing of repositories also shown on the overview page
|
||||
our $strict_export = "++GITWEB_STRICT_EXPORT++";
|
||||
|
||||
# list of git base URLs used for URL to where fetch project from,
|
||||
# i.e. full URL is "$git_base_url/$project"
|
||||
our @git_base_url_list = ("++GITWEB_BASE_URL++");
|
||||
@@ -196,23 +203,16 @@ if (defined $action) {
|
||||
}
|
||||
}
|
||||
|
||||
our $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
|
||||
our $project = $cgi->param('p');
|
||||
if (defined $project) {
|
||||
$project =~ s|^/||;
|
||||
$project =~ s|/$||;
|
||||
$project = undef unless $project;
|
||||
}
|
||||
if (defined $project) {
|
||||
if (!validate_input($project)) {
|
||||
die_error(undef, "Invalid project parameter");
|
||||
}
|
||||
if (!(-d "$projectroot/$project")) {
|
||||
die_error(undef, "No such directory");
|
||||
}
|
||||
if (!(-e "$projectroot/$project/HEAD")) {
|
||||
if (!validate_input($project) ||
|
||||
!(-d "$projectroot/$project") ||
|
||||
!(-e "$projectroot/$project/HEAD") ||
|
||||
($export_ok && !(-e "$projectroot/$project/$export_ok")) ||
|
||||
($strict_export && !project_in_list($project))) {
|
||||
undef $project;
|
||||
die_error(undef, "No such project");
|
||||
}
|
||||
$git_dir = "$projectroot/$project";
|
||||
}
|
||||
|
||||
our $file_name = $cgi->param('f');
|
||||
@@ -272,6 +272,32 @@ if (defined $searchtext) {
|
||||
$searchtext = quotemeta $searchtext;
|
||||
}
|
||||
|
||||
# now read PATH_INFO and use it as alternative to parameters
|
||||
our $path_info = $ENV{"PATH_INFO"};
|
||||
$path_info =~ s|^/||;
|
||||
$path_info =~ s|/$||;
|
||||
if (validate_input($path_info) && !defined $project) {
|
||||
$project = $path_info;
|
||||
while ($project && !-e "$projectroot/$project/HEAD") {
|
||||
$project =~ s,/*[^/]*$,,;
|
||||
}
|
||||
if (defined $project) {
|
||||
$project = undef unless $project;
|
||||
}
|
||||
if ($path_info =~ m,^$project/([^/]+)/(.+)$,) {
|
||||
# we got "project.git/branch/filename"
|
||||
$action ||= "blob_plain";
|
||||
$hash_base ||= $1;
|
||||
$file_name ||= $2;
|
||||
} elsif ($path_info =~ m,^$project/([^/]+)$,) {
|
||||
# we got "project.git/branch"
|
||||
$action ||= "shortlog";
|
||||
$hash ||= $1;
|
||||
}
|
||||
}
|
||||
|
||||
$git_dir = "$projectroot/$project";
|
||||
|
||||
# dispatch
|
||||
my %actions = (
|
||||
"blame" => \&git_blame2,
|
||||
@@ -405,6 +431,12 @@ sub untabify {
|
||||
return $line;
|
||||
}
|
||||
|
||||
sub project_in_list {
|
||||
my $project = shift;
|
||||
my @list = git_get_projects_list();
|
||||
return @list && scalar(grep { $_->{'path'} eq $project } @list);
|
||||
}
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## HTML aware string manipulation
|
||||
|
||||
@@ -717,7 +749,8 @@ sub git_get_projects_list {
|
||||
|
||||
my $subdir = substr($File::Find::name, $pfxlen + 1);
|
||||
# we check related file in $projectroot
|
||||
if (-e "$projectroot/$subdir/HEAD") {
|
||||
if (-e "$projectroot/$subdir/HEAD" && (!$export_ok ||
|
||||
-e "$projectroot/$subdir/$export_ok")) {
|
||||
push @list, { path => $subdir };
|
||||
$File::Find::prune = 1;
|
||||
}
|
||||
@@ -738,7 +771,8 @@ sub git_get_projects_list {
|
||||
if (!defined $path) {
|
||||
next;
|
||||
}
|
||||
if (-e "$projectroot/$path/HEAD") {
|
||||
if (-e "$projectroot/$path/HEAD" && (!$export_ok ||
|
||||
-e "$projectroot/$path/$export_ok")) {
|
||||
my $pr = {
|
||||
path => $path,
|
||||
owner => decode("utf8", $owner, Encode::FB_DEFAULT),
|
||||
@@ -2527,11 +2561,7 @@ sub git_heads {
|
||||
}
|
||||
|
||||
sub git_blob_plain {
|
||||
# blobs defined by non-textual hash id's can be cached
|
||||
my $expires;
|
||||
if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
|
||||
$expires = "+1d";
|
||||
}
|
||||
|
||||
if (!defined $hash) {
|
||||
if (defined $file_name) {
|
||||
@@ -2541,7 +2571,11 @@ sub git_blob_plain {
|
||||
} else {
|
||||
die_error(undef, "No file name defined");
|
||||
}
|
||||
} elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) {
|
||||
# blobs defined by non-textual hash id's can be cached
|
||||
$expires = "+1d";
|
||||
}
|
||||
|
||||
my $type = shift;
|
||||
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
|
||||
or die_error(undef, "Couldn't cat $file_name, $hash");
|
||||
@@ -2569,11 +2603,7 @@ sub git_blob_plain {
|
||||
}
|
||||
|
||||
sub git_blob {
|
||||
# blobs defined by non-textual hash id's can be cached
|
||||
my $expires;
|
||||
if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
|
||||
$expires = "+1d";
|
||||
}
|
||||
|
||||
if (!defined $hash) {
|
||||
if (defined $file_name) {
|
||||
@@ -2583,7 +2613,11 @@ sub git_blob {
|
||||
} else {
|
||||
die_error(undef, "No file name defined");
|
||||
}
|
||||
} elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) {
|
||||
# blobs defined by non-textual hash id's can be cached
|
||||
$expires = "+1d";
|
||||
}
|
||||
|
||||
my ($have_blame) = gitweb_check_feature('blame');
|
||||
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
|
||||
or die_error(undef, "Couldn't cat $file_name, $hash");
|
||||
|
||||
@@ -19,51 +19,51 @@ n=$n_dir/fixes
|
||||
|
||||
test_expect_success \
|
||||
"create $m" \
|
||||
'git-update-ref $m $A &&
|
||||
test $A = $(cat .git/$m)'
|
||||
"git-update-ref $m $A &&
|
||||
test $A"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"create $m" \
|
||||
'git-update-ref $m $B $A &&
|
||||
test $B = $(cat .git/$m)'
|
||||
"git-update-ref $m $B $A &&
|
||||
test $B"' = $(cat .git/'"$m"')'
|
||||
rm -f .git/$m
|
||||
|
||||
test_expect_success \
|
||||
"fail to create $n" \
|
||||
'touch .git/$n_dir
|
||||
"touch .git/$n_dir
|
||||
git-update-ref $n $A >out 2>err
|
||||
test $? = 1 &&
|
||||
test "'$? = 1 &&
|
||||
test "" = "$(cat out)" &&
|
||||
grep "error: unable to resolve reference" err &&
|
||||
grep $n err'
|
||||
grep '"$n err"
|
||||
rm -f .git/$n_dir out err
|
||||
|
||||
test_expect_success \
|
||||
"create $m (by HEAD)" \
|
||||
'git-update-ref HEAD $A &&
|
||||
test $A = $(cat .git/$m)'
|
||||
"git-update-ref HEAD $A &&
|
||||
test $A"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"create $m (by HEAD)" \
|
||||
'git-update-ref HEAD $B $A &&
|
||||
test $B = $(cat .git/$m)'
|
||||
"git-update-ref HEAD $B $A &&
|
||||
test $B"' = $(cat .git/'"$m"')'
|
||||
rm -f .git/$m
|
||||
|
||||
test_expect_failure \
|
||||
'(not) create HEAD with old sha1' \
|
||||
'git-update-ref HEAD $A $B'
|
||||
"git-update-ref HEAD $A $B"
|
||||
test_expect_failure \
|
||||
"(not) prior created .git/$m" \
|
||||
'test -f .git/$m'
|
||||
"test -f .git/$m"
|
||||
rm -f .git/$m
|
||||
|
||||
test_expect_success \
|
||||
"create HEAD" \
|
||||
'git-update-ref HEAD $A'
|
||||
"git-update-ref HEAD $A"
|
||||
test_expect_failure \
|
||||
'(not) change HEAD with wrong SHA1' \
|
||||
'git-update-ref HEAD $B $Z'
|
||||
"git-update-ref HEAD $B $Z"
|
||||
test_expect_failure \
|
||||
"(not) changed .git/$m" \
|
||||
'test $B = $(cat .git/$m)'
|
||||
"test $B"' = $(cat .git/'"$m"')'
|
||||
rm -f .git/$m
|
||||
|
||||
mkdir -p .git/logs/refs/heads
|
||||
@@ -71,18 +71,18 @@ touch .git/logs/refs/heads/master
|
||||
test_expect_success \
|
||||
"create $m (logged by touch)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:30" \
|
||||
git-update-ref HEAD $A -m "Initial Creation" &&
|
||||
test $A = $(cat .git/$m)'
|
||||
git-update-ref HEAD '"$A"' -m "Initial Creation" &&
|
||||
test '"$A"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"update $m (logged by touch)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:31" \
|
||||
git-update-ref HEAD $B $A -m "Switch" &&
|
||||
test $B = $(cat .git/$m)'
|
||||
git-update-ref HEAD'" $B $A "'-m "Switch" &&
|
||||
test '"$B"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"set $m (logged by touch)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:41" \
|
||||
git-update-ref HEAD $A &&
|
||||
test $A = $(cat .git/$m)'
|
||||
git-update-ref HEAD'" $A &&
|
||||
test $A"' = $(cat .git/'"$m"')'
|
||||
|
||||
cat >expect <<EOF
|
||||
$Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 Initial Creation
|
||||
@@ -91,7 +91,7 @@ $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
|
||||
EOF
|
||||
test_expect_success \
|
||||
"verifying $m's log" \
|
||||
'diff expect .git/logs/$m'
|
||||
"diff expect .git/logs/$m"
|
||||
rm -rf .git/$m .git/logs expect
|
||||
|
||||
test_expect_success \
|
||||
@@ -102,18 +102,18 @@ test_expect_success \
|
||||
test_expect_success \
|
||||
"create $m (logged by config)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:32" \
|
||||
git-update-ref HEAD $A -m "Initial Creation" &&
|
||||
test $A = $(cat .git/$m)'
|
||||
git-update-ref HEAD'" $A "'-m "Initial Creation" &&
|
||||
test '"$A"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"update $m (logged by config)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:33" \
|
||||
git-update-ref HEAD $B $A -m "Switch" &&
|
||||
test $B = $(cat .git/$m)'
|
||||
git-update-ref HEAD'" $B $A "'-m "Switch" &&
|
||||
test '"$B"' = $(cat .git/'"$m"')'
|
||||
test_expect_success \
|
||||
"set $m (logged by config)" \
|
||||
'GIT_COMMITTER_DATE="2005-05-26 23:43" \
|
||||
git-update-ref HEAD $A &&
|
||||
test $A = $(cat .git/$m)'
|
||||
git-update-ref HEAD '"$A &&
|
||||
test $A"' = $(cat .git/'"$m"')'
|
||||
|
||||
cat >expect <<EOF
|
||||
$Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000 Initial Creation
|
||||
@@ -140,50 +140,50 @@ test_expect_success \
|
||||
'Query "master@{May 25 2005}" (before history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{May 25 2005}" >o 2>e &&
|
||||
test $C = $(cat o) &&
|
||||
test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
|
||||
test '"$C"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
"Query master@{2005-05-25} (before history)" \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify master@{2005-05-25} >o 2>e &&
|
||||
test $C = $(cat o) &&
|
||||
echo test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
|
||||
test '"$C"' = $(cat o) &&
|
||||
echo test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
|
||||
test $C = $(cat o) &&
|
||||
test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
|
||||
test '"$C"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
|
||||
test $A = $(cat o) &&
|
||||
test '"$A"' = $(cat o) &&
|
||||
test "" = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
|
||||
test $B = $(cat o) &&
|
||||
test "warning: Log .git/logs/$m has gap after $gd." = "$(cat e)"'
|
||||
test '"$B"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
|
||||
test $Z = $(cat o) &&
|
||||
test '"$Z"' = $(cat o) &&
|
||||
test "" = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
|
||||
test $E = $(cat o) &&
|
||||
test '"$E"' = $(cat o) &&
|
||||
test "" = "$(cat e)"'
|
||||
test_expect_success \
|
||||
'Query "master@{2005-05-28}" (past end of history)' \
|
||||
'rm -f o e
|
||||
git-rev-parse --verify "master@{2005-05-28}" >o 2>e &&
|
||||
test $D = $(cat o) &&
|
||||
test "warning: Log .git/logs/$m unexpectedly ended on $ld." = "$(cat e)"'
|
||||
test '"$D"' = $(cat o) &&
|
||||
test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"'
|
||||
|
||||
|
||||
rm -f .git/$m .git/logs/$m expect
|
||||
@@ -221,7 +221,7 @@ $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 c
|
||||
EOF
|
||||
test_expect_success \
|
||||
'git-commit logged updates' \
|
||||
'diff expect .git/logs/$m'
|
||||
"diff expect .git/logs/$m"
|
||||
unset h_TEST h_OTHER h_FIXED h_MERGED
|
||||
|
||||
test_expect_success \
|
||||
|
||||
@@ -37,7 +37,9 @@ test_expect_success setup '
|
||||
git branch skip-merge skip-reference
|
||||
'
|
||||
|
||||
test_expect_failure 'rebase with git am -3 (default)' 'git rebase master'
|
||||
test_expect_failure 'rebase with git am -3 (default)' '
|
||||
git rebase master
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --skip with am -3' '
|
||||
git reset --hard HEAD &&
|
||||
|
||||
115
t/t4104-apply-boundary.sh
Executable file
115
t/t4104-apply-boundary.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2005 Junio C Hamano
|
||||
#
|
||||
|
||||
test_description='git-apply boundary tests
|
||||
|
||||
'
|
||||
. ./test-lib.sh
|
||||
|
||||
L="c d e f g h i j k l m n o p q r s t u v w x"
|
||||
|
||||
test_expect_success setup '
|
||||
for i in b '"$L"' y
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >original &&
|
||||
git update-index --add victim &&
|
||||
|
||||
: add to the head
|
||||
for i in a b '"$L"' y
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >add-a-expect &&
|
||||
git diff victim >add-a-patch.with &&
|
||||
git diff --unified=0 >add-a-patch.without &&
|
||||
|
||||
: modify at the head
|
||||
for i in a '"$L"' y
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >mod-a-expect &&
|
||||
git diff victim >mod-a-patch.with &&
|
||||
git diff --unified=0 >mod-a-patch.without &&
|
||||
|
||||
: remove from the head
|
||||
for i in '"$L"' y
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >del-a-expect &&
|
||||
git diff victim >del-a-patch.with
|
||||
git diff --unified=0 >del-a-patch.without &&
|
||||
|
||||
: add to the tail
|
||||
for i in b '"$L"' y z
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >add-z-expect &&
|
||||
git diff victim >add-z-patch.with &&
|
||||
git diff --unified=0 >add-z-patch.without &&
|
||||
|
||||
: modify at the tail
|
||||
for i in a '"$L"' y
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >mod-z-expect &&
|
||||
git diff victim >mod-z-patch.with &&
|
||||
git diff --unified=0 >mod-z-patch.without &&
|
||||
|
||||
: remove from the tail
|
||||
for i in b '"$L"'
|
||||
do
|
||||
echo $i
|
||||
done >victim &&
|
||||
cat victim >del-z-expect &&
|
||||
git diff victim >del-z-patch.with
|
||||
git diff --unified=0 >del-z-patch.without &&
|
||||
|
||||
: done
|
||||
'
|
||||
|
||||
for with in with without
|
||||
do
|
||||
case "$with" in
|
||||
with) u= ;;
|
||||
without) u='--unidiff-zero ' ;;
|
||||
esac
|
||||
for kind in add-a add-z mod-a mod-z del-a del-z
|
||||
do
|
||||
test_expect_success "apply $kind-patch $with context" '
|
||||
cat original >victim &&
|
||||
git update-index victim &&
|
||||
git apply --index '"$u$kind-patch.$with"' || {
|
||||
cat '"$kind-patch.$with"'
|
||||
(exit 1)
|
||||
} &&
|
||||
diff -u '"$kind"'-expect victim
|
||||
'
|
||||
done
|
||||
done
|
||||
|
||||
for kind in add-a add-z mod-a mod-z del-a del-z
|
||||
do
|
||||
rm -f $kind-ng.without
|
||||
sed -e "s/^diff --git /diff /" \
|
||||
-e '/^index /d' \
|
||||
<$kind-patch.without >$kind-ng.without
|
||||
test_expect_success "apply non-git $kind-patch without context" '
|
||||
cat original >victim &&
|
||||
git update-index victim &&
|
||||
git apply --unidiff-zero --index '"$kind-ng.without"' || {
|
||||
cat '"$kind-ng.without"'
|
||||
(exit 1)
|
||||
} &&
|
||||
diff -u '"$kind"'-expect victim
|
||||
'
|
||||
done
|
||||
|
||||
test_done
|
||||
Reference in New Issue
Block a user