mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
Merge branch 'cc/trace' into next
* cc/trace: Trace into open fd and refactor tracing code. t5710: fix two thinkos. gitweb: Extend parse_difftree_raw_line to save commit info gitweb: Separate printing of git_tree row into git_print_tree_entry gitweb: Move git-ls-tree output parsing to parse_ls_tree_line use do() instead of require() to include configuration gitweb: Remove forgotten call to git_to_hash log-tree.c: cleanup a bit append_signoff() Remove uneeded #include Makefile: fix typo unpack-objects: remove unused variable "eof" git-fsck-objects: lacking default references should not be fatal Check if pack directory exists prior to descending into it
This commit is contained in:
4
Makefile
4
Makefile
@@ -260,7 +260,7 @@ LIB_OBJS = \
|
||||
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
|
||||
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
|
||||
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
|
||||
write_or_die.o \
|
||||
write_or_die.o trace.o \
|
||||
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS)
|
||||
|
||||
BUILTIN_OBJS = \
|
||||
@@ -514,7 +514,7 @@ ifdef NO_SETENV
|
||||
COMPAT_CFLAGS += -DNO_SETENV
|
||||
COMPAT_OBJS += compat/setenv.o
|
||||
endif
|
||||
ifdef NO_SETENV
|
||||
ifdef NO_UNSETENV
|
||||
COMPAT_CFLAGS += -DNO_UNSETENV
|
||||
COMPAT_OBJS += compat/unsetenv.o
|
||||
endif
|
||||
|
||||
@@ -15,7 +15,7 @@ static const char unpack_usage[] = "git-unpack-objects [-n] [-q] < pack-file";
|
||||
|
||||
/* We always read in 4kB chunks. */
|
||||
static unsigned char buffer[4096];
|
||||
static unsigned long offset, len, eof;
|
||||
static unsigned long offset, len;
|
||||
static SHA_CTX ctx;
|
||||
|
||||
/*
|
||||
@@ -26,8 +26,6 @@ static void * fill(int min)
|
||||
{
|
||||
if (min <= len)
|
||||
return buffer + offset;
|
||||
if (eof)
|
||||
die("unable to fill input");
|
||||
if (min > sizeof(buffer))
|
||||
die("cannot fill %d bytes", min);
|
||||
if (offset) {
|
||||
|
||||
6
cache.h
6
cache.h
@@ -401,6 +401,7 @@ extern char git_commit_encoding[MAX_ENCODING_LENGTH];
|
||||
|
||||
extern int copy_fd(int ifd, int ofd);
|
||||
extern void write_or_die(int fd, const void *buf, size_t count);
|
||||
extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
|
||||
|
||||
/* Finish off pack transfer receiving end */
|
||||
extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int);
|
||||
@@ -426,4 +427,9 @@ extern struct commit *alloc_commit_node(void);
|
||||
extern struct tag *alloc_tag_node(void);
|
||||
extern void alloc_report(void);
|
||||
|
||||
/* trace.c */
|
||||
extern int nfvasprintf(char **str, const char *fmt, va_list va);
|
||||
extern void trace_printf(const char *format, ...);
|
||||
extern void trace_argv_printf(const char **argv, int count, const char *format, ...);
|
||||
|
||||
#endif /* CACHE_H */
|
||||
|
||||
18
exec_cmd.c
18
exec_cmd.c
@@ -97,26 +97,12 @@ int execv_git_cmd(const char **argv)
|
||||
tmp = argv[0];
|
||||
argv[0] = git_command;
|
||||
|
||||
if (getenv("GIT_TRACE")) {
|
||||
const char **p = argv;
|
||||
fputs("trace: exec:", stderr);
|
||||
while (*p) {
|
||||
fputc(' ', stderr);
|
||||
sq_quote_print(stderr, *p);
|
||||
++p;
|
||||
}
|
||||
putc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
trace_argv_printf(argv, -1, "trace: exec:");
|
||||
|
||||
/* execve() can only ever return if it fails */
|
||||
execve(git_command, (char **)argv, environ);
|
||||
|
||||
if (getenv("GIT_TRACE")) {
|
||||
fprintf(stderr, "trace: exec failed: %s\n",
|
||||
strerror(errno));
|
||||
fflush(stderr);
|
||||
}
|
||||
trace_printf("trace: exec failed: %s\n", strerror(errno));
|
||||
|
||||
argv[0] = tmp;
|
||||
}
|
||||
|
||||
@@ -425,8 +425,23 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1)
|
||||
static void get_default_heads(void)
|
||||
{
|
||||
for_each_ref(fsck_handle_ref);
|
||||
if (!default_refs)
|
||||
die("No default references");
|
||||
|
||||
/*
|
||||
* Not having any default heads isn't really fatal, but
|
||||
* it does mean that "--unreachable" no longer makes any
|
||||
* sense (since in this case everything will obviously
|
||||
* be unreachable by definition.
|
||||
*
|
||||
* Showing dangling objects is valid, though (as those
|
||||
* dangling objects are likely lost heads).
|
||||
*
|
||||
* So we just print a warning about it, and clear the
|
||||
* "show_unreachable" flag.
|
||||
*/
|
||||
if (!default_refs) {
|
||||
error("No default references");
|
||||
show_unreachable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsck_object_dir(const char *path)
|
||||
|
||||
@@ -38,7 +38,7 @@ case ",$all_into_one," in
|
||||
pack_objects=
|
||||
|
||||
# Redundancy check in all-into-one case is trivial.
|
||||
existing=`cd "$PACKDIR" && \
|
||||
existing=`test -d "$PACKDIR" && cd "$PACKDIR" && \
|
||||
find . -type f \( -name '*.pack' -o -name '*.idx' \) -print`
|
||||
;;
|
||||
esac
|
||||
|
||||
25
git.c
25
git.c
@@ -179,17 +179,9 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
if (!strcmp(alias_command, new_argv[0]))
|
||||
die("recursive alias: %s", alias_command);
|
||||
|
||||
if (getenv("GIT_TRACE")) {
|
||||
int i;
|
||||
fprintf(stderr, "trace: alias expansion: %s =>",
|
||||
alias_command);
|
||||
for (i = 0; i < count; ++i) {
|
||||
fputc(' ', stderr);
|
||||
sq_quote_print(stderr, new_argv[i]);
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
trace_argv_printf(new_argv, count,
|
||||
"trace: alias expansion: %s =>",
|
||||
alias_command);
|
||||
|
||||
new_argv = xrealloc(new_argv, sizeof(char*) *
|
||||
(count + *argcp + 1));
|
||||
@@ -292,16 +284,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||
prefix = setup_git_directory();
|
||||
if (p->option & USE_PAGER)
|
||||
setup_pager();
|
||||
if (getenv("GIT_TRACE")) {
|
||||
int j;
|
||||
fprintf(stderr, "trace: built-in: git");
|
||||
for (j = 0; j < argc; ++j) {
|
||||
fputc(' ', stderr);
|
||||
sq_quote_print(stderr, argv[j]);
|
||||
}
|
||||
putc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
trace_argv_printf(argv, argc, "trace: built-in: git");
|
||||
|
||||
exit(p->fn(argc, argv, prefix));
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ sub feature_snapshot {
|
||||
our @diff_opts = ('-M'); # taken from git_commit
|
||||
|
||||
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
|
||||
require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
|
||||
do $GITWEB_CONFIG if -e $GITWEB_CONFIG;
|
||||
|
||||
# version of the core git binary
|
||||
our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown";
|
||||
@@ -1027,9 +1027,30 @@ sub parse_difftree_raw_line {
|
||||
}
|
||||
}
|
||||
# 'c512b523472485aef4fff9e57b229d9d243c967f'
|
||||
#elsif ($line =~ m/^([0-9a-fA-F]{40})$/) {
|
||||
# $res{'commit'} = $1;
|
||||
#}
|
||||
elsif ($line =~ m/^([0-9a-fA-F]{40})$/) {
|
||||
$res{'commit'} = $1;
|
||||
}
|
||||
|
||||
return wantarray ? %res : \%res;
|
||||
}
|
||||
|
||||
# parse line of git-ls-tree output
|
||||
sub parse_ls_tree_line ($;%) {
|
||||
my $line = shift;
|
||||
my %opts = @_;
|
||||
my %res;
|
||||
|
||||
#'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
|
||||
$line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/;
|
||||
|
||||
$res{'mode'} = $1;
|
||||
$res{'type'} = $2;
|
||||
$res{'hash'} = $3;
|
||||
if ($opts{'-z'}) {
|
||||
$res{'name'} = $4;
|
||||
} else {
|
||||
$res{'name'} = unquote($4);
|
||||
}
|
||||
|
||||
return wantarray ? %res : \%res;
|
||||
}
|
||||
@@ -1454,6 +1475,62 @@ sub git_print_simplified_log {
|
||||
-remove_title => $remove_title);
|
||||
}
|
||||
|
||||
# print tree entry (row of git_tree), but without encompassing <tr> element
|
||||
sub git_print_tree_entry {
|
||||
my ($t, $basedir, $hash_base, $have_blame) = @_;
|
||||
|
||||
my %base_key = ();
|
||||
$base_key{hash_base} = $hash_base if defined $hash_base;
|
||||
|
||||
print "<td class=\"mode\">" . mode_str($t->{'mode'}) . "</td>\n";
|
||||
if ($t->{'type'} eq "blob") {
|
||||
print "<td class=\"list\">" .
|
||||
$cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
|
||||
file_name=>"$basedir$t->{'name'}", %base_key),
|
||||
-class => "list"}, esc_html($t->{'name'})) .
|
||||
"</td>\n" .
|
||||
"<td class=\"link\">" .
|
||||
$cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
|
||||
file_name=>"$basedir$t->{'name'}", %base_key)},
|
||||
"blob");
|
||||
if ($have_blame) {
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"blame", hash=>$t->{'hash'},
|
||||
file_name=>"$basedir$t->{'name'}", %base_key)},
|
||||
"blame");
|
||||
}
|
||||
if (defined $hash_base) {
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
|
||||
hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}")},
|
||||
"history");
|
||||
}
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"blob_plain",
|
||||
hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}")},
|
||||
"raw") .
|
||||
"</td>\n";
|
||||
|
||||
} elsif ($t->{'type'} eq "tree") {
|
||||
print "<td class=\"list\">" .
|
||||
$cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
|
||||
file_name=>"$basedir$t->{'name'}", %base_key)},
|
||||
esc_html($t->{'name'})) .
|
||||
"</td>\n" .
|
||||
"<td class=\"link\">" .
|
||||
$cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
|
||||
file_name=>"$basedir$t->{'name'}", %base_key)},
|
||||
"tree");
|
||||
if (defined $hash_base) {
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
|
||||
file_name=>"$basedir$t->{'name'}")},
|
||||
"history");
|
||||
}
|
||||
print "</td>\n";
|
||||
}
|
||||
}
|
||||
|
||||
## ......................................................................
|
||||
## functions printing large fragments of HTML
|
||||
|
||||
@@ -2492,14 +2569,13 @@ sub git_tree {
|
||||
my $refs = git_get_references();
|
||||
my $ref = format_ref_marker($refs, $hash_base);
|
||||
git_header_html();
|
||||
my %base_key = ();
|
||||
my $base = "";
|
||||
my $have_blame = gitweb_check_feature('blame');
|
||||
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
|
||||
$base_key{hash_base} = $hash_base;
|
||||
git_print_page_nav('tree','', $hash_base);
|
||||
git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
|
||||
} else {
|
||||
undef $hash_base;
|
||||
print "<div class=\"page_nav\">\n";
|
||||
print "<br/><br/></div>\n";
|
||||
print "<div class=\"title\">$hash</div>\n";
|
||||
@@ -2512,54 +2588,17 @@ sub git_tree {
|
||||
print "<table cellspacing=\"0\">\n";
|
||||
my $alternate = 0;
|
||||
foreach my $line (@entries) {
|
||||
#'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
|
||||
$line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/;
|
||||
my $t_mode = $1;
|
||||
my $t_type = $2;
|
||||
my $t_hash = $3;
|
||||
my $t_name = validate_input($4);
|
||||
my %t = parse_ls_tree_line($line, -z => 1);
|
||||
|
||||
if ($alternate) {
|
||||
print "<tr class=\"dark\">\n";
|
||||
} else {
|
||||
print "<tr class=\"light\">\n";
|
||||
}
|
||||
$alternate ^= 1;
|
||||
print "<td class=\"mode\">" . mode_str($t_mode) . "</td>\n";
|
||||
if ($t_type eq "blob") {
|
||||
print "<td class=\"list\">" .
|
||||
$cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key),
|
||||
-class => "list"}, esc_html($t_name)) .
|
||||
"</td>\n" .
|
||||
"<td class=\"link\">" .
|
||||
$cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
|
||||
"blob");
|
||||
if ($have_blame) {
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"blame", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
|
||||
"blame");
|
||||
}
|
||||
print " | " .
|
||||
$cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
|
||||
hash=>$t_hash, file_name=>"$base$t_name")},
|
||||
"history") .
|
||||
" | " .
|
||||
$cgi->a({-href => href(action=>"blob_plain",
|
||||
hash=>$t_hash, file_name=>"$base$t_name")},
|
||||
"raw") .
|
||||
"</td>\n";
|
||||
} elsif ($t_type eq "tree") {
|
||||
print "<td class=\"list\">" .
|
||||
$cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
|
||||
esc_html($t_name)) .
|
||||
"</td>\n" .
|
||||
"<td class=\"link\">" .
|
||||
$cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
|
||||
"tree") .
|
||||
" | " .
|
||||
$cgi->a({-href => href(action=>"history", hash_base=>$hash_base, file_name=>"$base$t_name")},
|
||||
"history") .
|
||||
"</td>\n";
|
||||
}
|
||||
|
||||
git_print_tree_entry(\%t, $base, $hash_base, $have_blame);
|
||||
|
||||
print "</tr>\n";
|
||||
}
|
||||
print "</table>\n" .
|
||||
@@ -2778,10 +2817,6 @@ sub git_blobdiff {
|
||||
@difftree
|
||||
or die_error('404 Not Found', "Blob diff not found");
|
||||
|
||||
} elsif (defined $hash) { # try to find filename from $hash
|
||||
if ($hash !~ /[0-9a-fA-F]{40}/) {
|
||||
$hash = git_to_hash($hash);
|
||||
}
|
||||
} elsif (defined $hash &&
|
||||
$hash =~ /[0-9a-fA-F]{40}/) {
|
||||
# try to find filename from $hash
|
||||
|
||||
25
imap-send.c
25
imap-send.c
@@ -110,7 +110,6 @@ static char *next_arg( char ** );
|
||||
|
||||
static void free_generic_messages( message_t * );
|
||||
|
||||
static int nfvasprintf( char **str, const char *fmt, va_list va );
|
||||
static int nfsnprintf( char *buf, int blen, const char *fmt, ... );
|
||||
|
||||
|
||||
@@ -371,21 +370,6 @@ free_generic_messages( message_t *msgs )
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
git_vasprintf( char **strp, const char *fmt, va_list ap )
|
||||
{
|
||||
int len;
|
||||
char tmp[1024];
|
||||
|
||||
if ((len = vsnprintf( tmp, sizeof(tmp), fmt, ap )) < 0 || !(*strp = xmalloc( len + 1 )))
|
||||
return -1;
|
||||
if (len >= (int)sizeof(tmp))
|
||||
vsprintf( *strp, fmt, ap );
|
||||
else
|
||||
memcpy( *strp, tmp, len + 1 );
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
nfsnprintf( char *buf, int blen, const char *fmt, ... )
|
||||
{
|
||||
@@ -399,15 +383,6 @@ nfsnprintf( char *buf, int blen, const char *fmt, ... )
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nfvasprintf( char **str, const char *fmt, va_list va )
|
||||
{
|
||||
int ret = git_vasprintf( str, fmt, va );
|
||||
if (ret < 0)
|
||||
die( "Fatal: Out of memory\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct {
|
||||
unsigned char i, j, s[256];
|
||||
} rs;
|
||||
|
||||
116
log-tree.c
116
log-tree.c
@@ -12,10 +12,58 @@ static void show_parents(struct commit *commit, int abbrev)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
|
||||
* Signed-off-by: and Acked-by: lines.
|
||||
*/
|
||||
static int detect_any_signoff(char *letter, int size)
|
||||
{
|
||||
char ch, *cp;
|
||||
int seen_colon = 0;
|
||||
int seen_at = 0;
|
||||
int seen_name = 0;
|
||||
int seen_head = 0;
|
||||
|
||||
cp = letter + size;
|
||||
while (letter <= --cp && (ch = *cp) == '\n')
|
||||
continue;
|
||||
|
||||
while (letter <= cp) {
|
||||
ch = *cp--;
|
||||
if (ch == '\n')
|
||||
break;
|
||||
|
||||
if (!seen_at) {
|
||||
if (ch == '@')
|
||||
seen_at = 1;
|
||||
continue;
|
||||
}
|
||||
if (!seen_colon) {
|
||||
if (ch == '@')
|
||||
return 0;
|
||||
else if (ch == ':')
|
||||
seen_colon = 1;
|
||||
else
|
||||
seen_name = 1;
|
||||
continue;
|
||||
}
|
||||
if (('A' <= ch && ch <= 'Z') ||
|
||||
('a' <= ch && ch <= 'z') ||
|
||||
ch == '-') {
|
||||
seen_head = 1;
|
||||
continue;
|
||||
}
|
||||
/* no empty last line doesn't match */
|
||||
return 0;
|
||||
}
|
||||
return seen_head && seen_name;
|
||||
}
|
||||
|
||||
static int append_signoff(char *buf, int buf_sz, int at, const char *signoff)
|
||||
{
|
||||
int signoff_len = strlen(signoff);
|
||||
static const char signed_off_by[] = "Signed-off-by: ";
|
||||
int signoff_len = strlen(signoff);
|
||||
int has_signoff = 0;
|
||||
char *cp = buf;
|
||||
|
||||
/* Do we have enough space to add it? */
|
||||
@@ -23,58 +71,26 @@ static int append_signoff(char *buf, int buf_sz, int at, const char *signoff)
|
||||
return at;
|
||||
|
||||
/* First see if we already have the sign-off by the signer */
|
||||
while (1) {
|
||||
cp = strstr(cp, signed_off_by);
|
||||
if (!cp)
|
||||
break;
|
||||
while ((cp = strstr(cp, signed_off_by))) {
|
||||
|
||||
has_signoff = 1;
|
||||
|
||||
cp += strlen(signed_off_by);
|
||||
if ((cp + signoff_len < buf + at) &&
|
||||
!strncmp(cp, signoff, signoff_len) &&
|
||||
isspace(cp[signoff_len]))
|
||||
return at; /* we already have him */
|
||||
if (cp + signoff_len >= buf + at)
|
||||
break;
|
||||
if (strncmp(cp, signoff, signoff_len))
|
||||
continue;
|
||||
if (!isspace(cp[signoff_len]))
|
||||
continue;
|
||||
/* we already have him */
|
||||
return at;
|
||||
}
|
||||
|
||||
/* Does the last line already end with "^[-A-Za-z]+: [^@]+@"?
|
||||
* If not, add a blank line to separate the message from
|
||||
* the run of Signed-off-by: and Acked-by: lines.
|
||||
*/
|
||||
{
|
||||
char ch;
|
||||
int seen_colon, seen_at, seen_name, seen_head, not_signoff;
|
||||
seen_colon = 0;
|
||||
seen_at = 0;
|
||||
seen_name = 0;
|
||||
seen_head = 0;
|
||||
not_signoff = 0;
|
||||
cp = buf + at;
|
||||
while (buf <= --cp && (ch = *cp) == '\n')
|
||||
;
|
||||
while (!not_signoff && buf <= cp && (ch = *cp--) != '\n') {
|
||||
if (!seen_at) {
|
||||
if (ch == '@')
|
||||
seen_at = 1;
|
||||
continue;
|
||||
}
|
||||
if (!seen_colon) {
|
||||
if (ch == '@')
|
||||
not_signoff = 1;
|
||||
else if (ch == ':')
|
||||
seen_colon = 1;
|
||||
else
|
||||
seen_name = 1;
|
||||
continue;
|
||||
}
|
||||
if (('A' <= ch && ch <= 'Z') ||
|
||||
('a' <= ch && ch <= 'z') ||
|
||||
ch == '-') {
|
||||
seen_head = 1;
|
||||
continue;
|
||||
}
|
||||
not_signoff = 1;
|
||||
}
|
||||
if (not_signoff || !seen_head || !seen_name)
|
||||
buf[at++] = '\n';
|
||||
}
|
||||
if (!has_signoff)
|
||||
has_signoff = detect_any_signoff(buf, at);
|
||||
|
||||
if (!has_signoff)
|
||||
buf[at++] = '\n';
|
||||
|
||||
strcpy(buf + at, signed_off_by);
|
||||
at += strlen(signed_off_by);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "cache.h"
|
||||
#include "refs.h"
|
||||
#include "pkt-line.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
static const char peek_remote_usage[] =
|
||||
"git-peek-remote [--exec=upload-pack] [host:]directory";
|
||||
|
||||
32
quote.c
32
quote.c
@@ -74,6 +74,38 @@ char *sq_quote(const char *src)
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *sq_quote_argv(const char** argv, int count)
|
||||
{
|
||||
char *buf, *to;
|
||||
int i;
|
||||
size_t len = 0;
|
||||
|
||||
/* Count argv if needed. */
|
||||
if (count < 0) {
|
||||
for (count = 0; argv[count]; count++)
|
||||
; /* just counting */
|
||||
}
|
||||
|
||||
/* Special case: no argv. */
|
||||
if (!count)
|
||||
return xcalloc(1,1);
|
||||
|
||||
/* Get destination buffer length. */
|
||||
for (i = 0; i < count; i++)
|
||||
len += sq_quote_buf(NULL, 0, argv[i]) + 1;
|
||||
|
||||
/* Alloc destination buffer. */
|
||||
to = buf = xmalloc(len + 1);
|
||||
|
||||
/* Copy into destination buffer. */
|
||||
for (i = 0; i < count; ++i) {
|
||||
*to++ = ' ';
|
||||
to += sq_quote_buf(to, len, argv[i]);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *sq_dequote(char *arg)
|
||||
{
|
||||
char *dst = arg;
|
||||
|
||||
1
quote.h
1
quote.h
@@ -31,6 +31,7 @@
|
||||
extern char *sq_quote(const char *src);
|
||||
extern void sq_quote_print(FILE *stream, const char *src);
|
||||
extern size_t sq_quote_buf(char *dst, size_t n, const char *src);
|
||||
extern char *sq_quote_argv(const char** argv, int count);
|
||||
|
||||
/* This unwraps what sq_quote() produces in place, but returns
|
||||
* NULL if the input does not look like what sq_quote would have
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "refs.h"
|
||||
#include "pkt-line.h"
|
||||
#include "run-command.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ test_expect_failure 'creating too deep nesting' \
|
||||
git clone -l -s D E &&
|
||||
git clone -l -s E F &&
|
||||
git clone -l -s F G &&
|
||||
git clone -l -s G H &&
|
||||
cd H &&
|
||||
test_valid_repo'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
@@ -28,7 +28,6 @@ unset GIT_DIR
|
||||
unset GIT_EXTERNAL_DIFF
|
||||
unset GIT_INDEX_FILE
|
||||
unset GIT_OBJECT_DIRECTORY
|
||||
unset GIT_TRACE
|
||||
unset SHA1_FILE_DIRECTORIES
|
||||
unset SHA1_FILE_DIRECTORY
|
||||
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
|
||||
|
||||
125
trace.c
Normal file
125
trace.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* GIT - The information manager from hell
|
||||
*
|
||||
* Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
|
||||
* Copyright (C) 2002-2004 Oswald Buddenhagen <ossi@users.sf.net>
|
||||
* Copyright (C) 2004 Theodore Y. Ts'o <tytso@mit.edu>
|
||||
* Copyright (C) 2006 Mike McCormack
|
||||
* Copyright (C) 2006 Christian Couder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "cache.h"
|
||||
#include "quote.h"
|
||||
|
||||
/* Stolen from "imap-send.c". */
|
||||
static int git_vasprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
int len;
|
||||
char tmp[1024];
|
||||
|
||||
if ((len = vsnprintf(tmp, sizeof(tmp), fmt, ap)) < 0 ||
|
||||
!(*strp = xmalloc(len + 1)))
|
||||
return -1;
|
||||
if (len >= (int)sizeof(tmp))
|
||||
vsprintf(*strp, fmt, ap);
|
||||
else
|
||||
memcpy(*strp, tmp, len + 1);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Stolen from "imap-send.c". */
|
||||
int nfvasprintf(char **str, const char *fmt, va_list va)
|
||||
{
|
||||
int ret = git_vasprintf(str, fmt, va);
|
||||
if (ret < 0)
|
||||
die("Fatal: Out of memory\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get a trace file descriptor from GIT_TRACE env variable. */
|
||||
static int get_trace_fd()
|
||||
{
|
||||
char *trace = getenv("GIT_TRACE");
|
||||
|
||||
if (!trace || !strcmp(trace, "0") || !strcasecmp(trace," false"))
|
||||
return 0;
|
||||
if (!strcmp(trace, "1") || !strcasecmp(trace, "true"))
|
||||
return STDERR_FILENO;
|
||||
if (strlen(trace) == 1 && isdigit(*trace))
|
||||
return atoi(trace);
|
||||
|
||||
fprintf(stderr, "What does '%s' for GIT_TRACE means ?\n", trace);
|
||||
fprintf(stderr, "Defaulting to tracing on stderr...\n");
|
||||
return STDERR_FILENO;
|
||||
}
|
||||
|
||||
static const char err_msg[] = "Could not trace into fd given by "
|
||||
"GIT_TRACE environment variable";
|
||||
|
||||
void trace_printf(const char *format, ...)
|
||||
{
|
||||
char *trace_str;
|
||||
va_list rest;
|
||||
int fd = get_trace_fd();
|
||||
|
||||
if (!fd)
|
||||
return;
|
||||
|
||||
va_start(rest, format);
|
||||
nfvasprintf(&trace_str, format, rest);
|
||||
va_end(rest);
|
||||
|
||||
write_or_whine(fd, trace_str, strlen(trace_str), err_msg);
|
||||
|
||||
free(trace_str);
|
||||
}
|
||||
|
||||
void trace_argv_printf(const char **argv, int count, const char *format, ...)
|
||||
{
|
||||
char *argv_str, *format_str, *trace_str;
|
||||
size_t argv_len, format_len, trace_len;
|
||||
va_list rest;
|
||||
int fd = get_trace_fd();
|
||||
|
||||
if (!fd)
|
||||
return;
|
||||
|
||||
/* Get the argv string. */
|
||||
argv_str = sq_quote_argv(argv, count);
|
||||
argv_len = strlen(argv_str);
|
||||
|
||||
/* Get the formated string. */
|
||||
va_start(rest, format);
|
||||
nfvasprintf(&format_str, format, rest);
|
||||
va_end(rest);
|
||||
|
||||
/* Allocate buffer for trace string. */
|
||||
format_len = strlen(format_str);
|
||||
trace_len = argv_len + format_len + 1; /* + 1 for \n */
|
||||
trace_str = xmalloc(trace_len + 1);
|
||||
|
||||
/* Copy everything into the trace string. */
|
||||
strncpy(trace_str, format_str, format_len);
|
||||
strncpy(trace_str + format_len, argv_str, argv_len);
|
||||
strcpy(trace_str + trace_len - 1, "\n");
|
||||
|
||||
write_or_whine(fd, trace_str, trace_len, err_msg);
|
||||
|
||||
free(argv_str);
|
||||
free(format_str);
|
||||
free(trace_str);
|
||||
}
|
||||
@@ -18,3 +18,28 @@ void write_or_die(int fd, const void *buf, size_t count)
|
||||
p += written;
|
||||
}
|
||||
}
|
||||
|
||||
int write_or_whine(int fd, const void *buf, size_t count, const char *msg)
|
||||
{
|
||||
const char *p = buf;
|
||||
ssize_t written;
|
||||
|
||||
while (count > 0) {
|
||||
written = xwrite(fd, p, count);
|
||||
if (written == 0) {
|
||||
fprintf(stderr, "%s: disk full?\n", msg);
|
||||
return 0;
|
||||
}
|
||||
else if (written < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit(0);
|
||||
fprintf(stderr, "%s: write error (%s)\n",
|
||||
msg, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
count -= written;
|
||||
p += written;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user