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:
Junio C Hamano
2006-09-17 03:12:03 -07:00
7 changed files with 319 additions and 172 deletions

View File

@@ -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' \

View File

@@ -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;

View File

@@ -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(&current_path, argv[2]);
strbuf_append_string(&current_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, &current_path, 040777, NULL, 0);
traverse_tree(&tree, &current_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);

View File

@@ -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");

View File

@@ -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 \

View File

@@ -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
View 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