summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-04-25 23:31:45 -0700
committerJunio C Hamano <junkio@cox.net>2007-04-25 23:31:45 -0700
commit6169a89c4fd29cf9c747bab7bd310877328bc7e2 (patch)
tree299d1cd315b66e377261901698bc128752466fc8
parenta7b02ccf9a682fa0c2b28df6ca20f9199cdca4de (diff)
parent8abe88a29c0789276c6d028b76b1190630b101c6 (diff)
downloadgit-6169a89c4fd29cf9c747bab7bd310877328bc7e2.tar.gz
Merge branch 'maint'
* maint: Start preparing for 1.5.1.3 Sanitize @to recipients. git-svn: Ignore usernames in URLs in find_by_url Document --dry-run and envelope-sender for git-send-email. Allow users to optionally specify their envelope sender. Ensure clean addresses are always used with Net::SMTP Validate @recipients before using it for sendmail and Net::SMTP. Perform correct quoting of recipient names. Change the scope of the $cc variable as it is not needed outside of send_message. Debugging cleanup improvements Prefix Dry- to the message status to denote dry-runs. Document --dry-run parameter to send-email. git-svn: Don't rely on $_ after making a function call Fix handle leak in write_tree Actually handle some-low memory conditions Conflicts: RelNotes git-send-email.perl
-rw-r--r--Documentation/RelNotes-1.5.1.3.txt38
-rw-r--r--Documentation/git-send-email.txt9
-rw-r--r--builtin-write-tree.c6
-rw-r--r--git-compat-util.h12
-rwxr-xr-xgit-send-email.perl55
-rwxr-xr-xgit-svn.perl14
-rw-r--r--sha1_file.c10
7 files changed, 111 insertions, 33 deletions
diff --git a/Documentation/RelNotes-1.5.1.3.txt b/Documentation/RelNotes-1.5.1.3.txt
new file mode 100644
index 0000000000..9a4b069ccc
--- /dev/null
+++ b/Documentation/RelNotes-1.5.1.3.txt
@@ -0,0 +1,38 @@
+GIT v1.5.1.3 Release Notes (draft)
+==========================
+
+Fixes since v1.5.1.2
+--------------------
+
+* Bugfixes
+
+ - git-add tried to optimize by finding common leading
+ directories across its arguments but botched, causing very
+ confused behaviour.
+
+ - unofficial rpm.spec file shipped with git was letting
+ ETC_GITCONFIG set to /usr/etc/gitconfig. Tweak the official
+ Makefile to make it harder for distro people to make the
+ same mistake, by setting the variable to /etc/gitconfig if
+ prefix is set to /usr.
+
+ - git-svn inconsistently stripped away username from the URL
+ only when svnsync_props was in use.
+
+ - git-send-email was not quoting recipient names that have
+ period '.' in them. Also it did not allow overriding
+ envelope sender, which made it impossible to send patches to
+ certain subscriber-only lists.
+
+ - built-in write_tree() routine had a sequence that renamed a
+ file that is still open, which some systems did not like.
+
+ - when memory is very tight, sliding mmap code to read
+ packfiles incorrectly closed the fd that was still being
+ used to read the pack.
+
+---
+exec >/var/tmp/1
+O=v1.5.1.2-23-gbf7af11
+echo O=`git describe refs/heads/maint`
+git shortlog --no-merges $O..refs/heads/maint
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 682313e95d..795db873fc 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -85,6 +85,15 @@ The --cc option must be repeated for each user you want on the cc list.
Do not add the From: address to the cc: list, if it shows up in a From:
line.
+--dry-run::
+ Do everything except actually send the emails.
+
+--envelope-sender::
+ Specify the envelope sender used to send the emails.
+ This is useful if your default address is not the address that is
+ subscribed to a list. If you use the sendmail binary, you must have
+ suitable privileges for the -f parameter.
+
--to::
Specify the primary recipient of the emails generated.
Generally, this will be the upstream maintainer of the
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index c88bbd1b9b..391de53972 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -36,8 +36,10 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
die("git-write-tree: error building trees");
if (0 <= newfd) {
if (!write_cache(newfd, active_cache, active_nr)
- && !close(newfd))
+ && !close(newfd)) {
commit_lock_file(lock_file);
+ newfd = -1;
+ }
}
/* Not being able to write is fine -- we are only interested
* in updating the cache-tree part, and if the next caller
@@ -55,6 +57,8 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
else
hashcpy(sha1, active_cache_tree->sha1);
+ if (0 <= newfd)
+ close(newfd);
rollback_lock_file(lock_file);
return 0;
diff --git a/git-compat-util.h b/git-compat-util.h
index 0b6d74d4d7..2c84016ac9 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -164,13 +164,13 @@ extern size_t gitstrlcpy(char *, const char *, size_t);
extern uintmax_t gitstrtoumax(const char *, char **, int);
#endif
-extern void release_pack_memory(size_t);
+extern void release_pack_memory(size_t, int);
static inline char* xstrdup(const char *str)
{
char *ret = strdup(str);
if (!ret) {
- release_pack_memory(strlen(str) + 1);
+ release_pack_memory(strlen(str) + 1, -1);
ret = strdup(str);
if (!ret)
die("Out of memory, strdup failed");
@@ -184,7 +184,7 @@ static inline void *xmalloc(size_t size)
if (!ret && !size)
ret = malloc(1);
if (!ret) {
- release_pack_memory(size);
+ release_pack_memory(size, -1);
ret = malloc(size);
if (!ret && !size)
ret = malloc(1);
@@ -203,7 +203,7 @@ static inline void *xrealloc(void *ptr, size_t size)
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret) {
- release_pack_memory(size);
+ release_pack_memory(size, -1);
ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
@@ -219,7 +219,7 @@ static inline void *xcalloc(size_t nmemb, size_t size)
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
if (!ret) {
- release_pack_memory(nmemb * size);
+ release_pack_memory(nmemb * size, -1);
ret = calloc(nmemb, size);
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
@@ -236,7 +236,7 @@ static inline void *xmmap(void *start, size_t length,
if (ret == MAP_FAILED) {
if (!length)
return NULL;
- release_pack_memory(length);
+ release_pack_memory(length, fd);
ret = mmap(start, length, prot, flags, fd, offset);
if (ret == MAP_FAILED)
die("Out of memory? mmap failed: %s", strerror(errno));
diff --git a/git-send-email.perl b/git-send-email.perl
index d6b15480dc..a6e3e02619 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -77,6 +77,10 @@ Options:
--quiet Make git-send-email less verbose. One line per email
should be all that is output.
+ --dry-run Do everything except actually send the emails.
+
+ --envelope-sender Specify the envelope sender used to send the emails.
+
EOT
exit(1);
}
@@ -137,6 +141,7 @@ my (@to,@cc,@initial_cc,@bcclist,@xh,
my ($chain_reply_to, $quiet, $suppress_from, $no_signed_off_cc,
$dry_run) = (1, 0, 0, 0, 0);
my $smtp_server;
+my $envelope_sender;
# Example reply to:
#$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';
@@ -175,6 +180,7 @@ my $rc = GetOptions("from=s" => \$from,
"suppress-from" => \$suppress_from,
"no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc,
"dry-run" => \$dry_run,
+ "envelope-sender=s" => \$envelope_sender,
);
unless ($rc) {
@@ -268,6 +274,7 @@ sub expand_aliases {
}
@to = expand_aliases(@to);
+@to = (map { sanitize_address_rfc822($_) } @to);
@initial_cc = expand_aliases(@initial_cc);
@bcclist = expand_aliases(@bcclist);
@@ -377,7 +384,7 @@ if (@files) {
}
# Variables we set as part of the loop over files
-our ($message_id, $cc, %mail, $subject, $reply_to, $references, $message);
+our ($message_id, %mail, $subject, $reply_to, $references, $message);
sub extract_valid_address {
my $address = shift;
@@ -418,7 +425,6 @@ sub make_message_id
-$cc = "";
$time = time - scalar $#files;
sub unquote_rfc2047 {
@@ -430,26 +436,37 @@ sub unquote_rfc2047 {
return "$_";
}
+# If an address contains a . in the name portion, the name must be quoted.
+sub sanitize_address_rfc822
+{
+ my ($recipient) = @_;
+ my ($recipient_name) = ($recipient =~ /^(.*?)\s+</);
+ if ($recipient_name && $recipient_name =~ /\./ && $recipient_name !~ /^".*"$/) {
+ my ($name, $addr) = ($recipient =~ /^(.*?)(\s+<.*)/);
+ $recipient = "\"$name\"$addr";
+ }
+ return $recipient;
+}
+
sub send_message
{
my @recipients = unique_email_list(@to);
+ @cc = (map { sanitize_address_rfc822($_) } @cc);
my $to = join (",\n\t", @recipients);
@recipients = unique_email_list(@recipients,@cc,@bcclist);
+ @recipients = (map { extract_valid_address($_) } @recipients);
my $date = format_2822_time($time++);
my $gitversion = '@@GIT_VERSION@@';
if ($gitversion =~ m/..GIT_VERSION../) {
$gitversion = Git::version();
}
- my ($author_name) = ($from =~ /^(.*?)\s+</);
- if ($author_name && $author_name =~ /\./ && $author_name !~ /^".*"$/) {
- my ($name, $addr) = ($from =~ /^(.*?)(\s+<.*)/);
- $from = "\"$name\"$addr";
- }
+ my $cc = join(", ", unique_email_list(@cc));
my $ccline = "";
if ($cc ne '') {
$ccline = "\nCc: $cc";
}
+ $from = sanitize_address_rfc822($from);
my $header = "From: $from
To: $to${ccline}
Subject: $subject
@@ -466,22 +483,27 @@ X-Mailer: git-send-email $gitversion
$header .= join("\n", @xh) . "\n";
}
+ my @sendmail_parameters = ('-i', @recipients);
+ my $raw_from = $from;
+ $raw_from = $envelope_sender if (defined $envelope_sender);
+ $raw_from = extract_valid_address($raw_from);
+ unshift (@sendmail_parameters,
+ '-f', $raw_from) if(defined $envelope_sender);
+
if ($dry_run) {
# We don't want to send the email.
} elsif ($smtp_server =~ m#^/#) {
my $pid = open my $sm, '|-';
defined $pid or die $!;
if (!$pid) {
- exec($smtp_server,'-i',
- map { extract_valid_address($_) }
- @recipients) or die $!;
+ exec($smtp_server, @sendmail_parameters) or die $!;
}
print $sm "$header\n$message";
close $sm or die $?;
} else {
require Net::SMTP;
$smtp ||= Net::SMTP->new( $smtp_server );
- $smtp->mail( $from ) or die $smtp->message;
+ $smtp->mail( $raw_from ) or die $smtp->message;
$smtp->to( @recipients ) or die $smtp->message;
$smtp->data or die $smtp->message;
$smtp->datasend("$header\n$message") or die $smtp->message;
@@ -489,13 +511,15 @@ X-Mailer: git-send-email $gitversion
$smtp->ok or die "Failed to send $subject\n".$smtp->message;
}
if ($quiet) {
- printf "Sent %s\n", $subject;
+ printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject);
} else {
- print "OK. Log says:\nDate: $date\n";
- if ($smtp) {
+ print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n");
+ if ($smtp_server !~ m#^/#) {
print "Server: $smtp_server\n";
+ print "MAIL FROM:<$raw_from>\n";
+ print "RCPT TO:".join(',',(map { "<$_>" } @recipients))."\n";
} else {
- print "Sendmail: $smtp_server\n";
+ print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n";
}
print "From: $from\nSubject: $subject\nCc: $cc\nTo: $to\n\n";
if ($smtp) {
@@ -590,7 +614,6 @@ foreach my $t (@files) {
$message = "From: $author_not_sender\n\n$message";
}
- $cc = join(", ", unique_email_list(@cc));
send_message();
diff --git a/git-svn.perl b/git-svn.perl
index 077d6b3a13..7b5f8ab3be 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -771,19 +771,19 @@ sub cmt_metadata {
sub working_head_info {
my ($head, $refs) = @_;
my ($fh, $ctx) = command_output_pipe('rev-list', $head);
- while (<$fh>) {
- chomp;
- my ($url, $rev, $uuid) = cmt_metadata($_);
+ while (my $hash = <$fh>) {
+ chomp($hash);
+ my ($url, $rev, $uuid) = cmt_metadata($hash);
if (defined $url && defined $rev) {
if (my $gs = Git::SVN->find_by_url($url)) {
my $c = $gs->rev_db_get($rev);
- if ($c && $c eq $_) {
+ if ($c && $c eq $hash) {
close $fh; # break the pipe
return ($url, $rev, $uuid, $gs);
}
}
}
- unshift @$refs, $_ if $refs;
+ unshift @$refs, $hash if $refs;
}
command_close_pipe($fh, $ctx);
(undef, undef, undef, undef);
@@ -1064,7 +1064,10 @@ sub init_remote_config {
sub find_by_url { # repos_root and, path are optional
my ($class, $full_url, $repos_root, $path) = @_;
+
return undef unless defined $full_url;
+ remove_username($full_url);
+ remove_username($repos_root) if defined $repos_root;
my $remotes = read_all_remotes();
if (defined $full_url && defined $repos_root && !defined $path) {
$path = $full_url;
@@ -1072,6 +1075,7 @@ sub find_by_url { # repos_root and, path are optional
}
foreach my $repo_id (keys %$remotes) {
my $u = $remotes->{$repo_id}->{url} or next;
+ remove_username($u);
next if defined $repos_root && $repos_root ne $u;
my $fetch = $remotes->{$repo_id}->{fetch} || {};
diff --git a/sha1_file.c b/sha1_file.c
index 06426640ea..32244d704e 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -549,7 +549,7 @@ static void scan_windows(struct packed_git *p,
}
}
-static int unuse_one_window(struct packed_git *current)
+static int unuse_one_window(struct packed_git *current, int keep_fd)
{
struct packed_git *p, *lru_p = NULL;
struct pack_window *lru_w = NULL, *lru_l = NULL;
@@ -565,7 +565,7 @@ static int unuse_one_window(struct packed_git *current)
lru_l->next = lru_w->next;
else {
lru_p->windows = lru_w->next;
- if (!lru_p->windows && lru_p != current) {
+ if (!lru_p->windows && lru_p->pack_fd != keep_fd) {
close(lru_p->pack_fd);
lru_p->pack_fd = -1;
}
@@ -577,10 +577,10 @@ static int unuse_one_window(struct packed_git *current)
return 0;
}
-void release_pack_memory(size_t need)
+void release_pack_memory(size_t need, int fd)
{
size_t cur = pack_mapped;
- while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
+ while (need >= (cur - pack_mapped) && unuse_one_window(NULL, fd))
; /* nothing */
}
@@ -713,7 +713,7 @@ unsigned char* use_pack(struct packed_git *p,
win->len = (size_t)len;
pack_mapped += win->len;
while (packed_git_limit < pack_mapped
- && unuse_one_window(p))
+ && unuse_one_window(p, p->pack_fd))
; /* nothing */
win->base = xmmap(NULL, win->len,
PROT_READ, MAP_PRIVATE,