* "git revert" did not properly fail when attempting to run with a
dirty index.
-Also included are a handful documentation updates.
+ * "git merge --no-commit --no-ff <other>" incorrectly made commits.
+
+ * "git merge --squash --no-ff <other>", which is a nonsense combination
+ of options, was not rejected.
+
+ * "git ls-remote" and "git remote show" against an empty repository
+ failed, instead of just giving an empty result (regression).
+
+ * "git fast-import" did not handle a renamed path whose name needs to be
+ quoted, due to a bug in unquote_c_style() function.
+
+ * "git cvsexportcommit" was confused when multiple files with the same
+ basename needed to be pushed out in the same commit.
+
+ * "git daemon" did not send early errors to syslog.
----
-exec >/var/tmp/1
-echo O=$(git describe maint)
-O=v1.5.4.3-32-g0f2d447
-git shortlog --no-merges $O..maint
+ * "git log --merge" did not work well with --left-right option.
+
+ * "git svn" promprted for client cert password every time it accessed the
+ server.
+
+ * The reset command in "git fast-import" data stream was documented to
+ end with an optional LF, but it actually required one.
+
+ * "git svn dcommit/rebase" did not honor --rewrite-root option.
+
+Also included are a handful documentation updates.
remote.<name>.receivepack::
The default program to execute on the remote side when pushing. See
- option \--exec of linkgit:git-push[1].
+ option \--receive-pack of linkgit:git-push[1].
remote.<name>.uploadpack::
The default program to execute on the remote side when fetching. See
- option \--exec of linkgit:git-fetch-pack[1].
+ option \--upload-pack of linkgit:git-fetch-pack[1].
remote.<name>.tagopt::
- Setting this value to --no-tags disables automatic tag following when fetching
- from remote <name>
+ Setting this value to \--no-tags disables automatic tag following when
+ fetching from remote <name>
remotes.<group>::
The list of remotes which are fetched by "git remote update
<repository> to pull from the local repository -- this is useful
when merging local branches into the current branch.
+Also note that options meant for `git-pull` itself and underlying
+`git-merge` must be given before the options meant for `git-fetch`.
OPTIONS
-------
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.4.3.GIT
+DEF_VER=v1.5.4.4.GIT
LF='
'
url = rewritten_url;
}
- walker = get_http_walker(url);
+ walker = get_http_walker(url, NULL);
walker->get_tree = get_tree;
walker->get_history = get_history;
walker->get_all = get_all;
usage(daemon_usage);
}
+ if (log_syslog) {
+ openlog("git-daemon", 0, LOG_DAEMON);
+ set_die_routine(daemon_die);
+ }
+
if (inetd_mode && (group_name || user_name))
die("--user and --group are incompatible with --inetd");
}
}
- if (log_syslog) {
- openlog("git-daemon", 0, LOG_DAEMON);
- set_die_routine(daemon_die);
- }
-
if (strict_paths && (!ok_paths || !*ok_paths))
die("option --strict-paths requires a whitelist");
+ if (base_path) {
+ struct stat st;
+
+ if (stat(base_path, &st) || !S_ISDIR(st.st_mode))
+ die("base-path '%s' does not exist or "
+ "is not a directory", base_path);
+ }
+
if (inetd_mode) {
struct sockaddr_storage ss;
struct sockaddr *peer = (struct sockaddr *)&ss;
else
b = new_branch(sp);
read_next_command();
- if (!cmd_from(b) && command_buf.len > 0)
+ cmd_from(b);
+ if (command_buf.len > 0)
unread_command_buf = 1;
}
my @updated = xargs_safe_pipe_capture([@cvs, 'update'], @canstatusfiles);
print @updated;
}
- my @cvsoutput;
- @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles);
- my $matchcount = 0;
- foreach my $l (@cvsoutput) {
- chomp $l;
- if ( $l =~ /^File:/ and $l =~ /Status: (.*)$/ ) {
- $cvsstat{$canstatusfiles[$matchcount]} = $1;
- $matchcount++;
+ # "cvs status" reorders the parameters, notably when there are multiple
+ # arguments with the same basename. So be precise here.
+
+ my %added = map { $_ => 1 } @afiles;
+ my %todo = map { $_ => 1 } @canstatusfiles;
+
+ while (%todo) {
+ my @canstatusfiles2 = ();
+ my %fullname = ();
+ foreach my $name (keys %todo) {
+ my $basename = basename($name);
+
+ $basename = "no file " . $basename if (exists($added{$basename}));
+ chomp($basename);
+
+ if (!exists($fullname{$basename})) {
+ $fullname{$basename} = $name;
+ push (@canstatusfiles2, $name);
+ delete($todo{$name});
}
+ }
+ my @cvsoutput;
+ @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles2);
+ foreach my $l (@cvsoutput) {
+ chomp $l;
+ if ($l =~ /^File:\s+(.*\S)\s+Status: (.*)$/) {
+ if (!exists($fullname{$1})) {
+ print STDERR "Huh? Status reported for unexpected file '$1'\n";
+ } else {
+ $cvsstat{$fullname{$1}} = $2;
+ }
+ }
+ }
}
}
ifeq ($(shell $(MSGFMT) >/dev/null 2>&1 || echo $$?),127)
MSGFMT := $(TCL_PATH) po/po2msg.sh
endif
+ ifeq (msgfmt,$(MSGFMT))
+ ifeq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null || echo $?),1)
+ MSGFMT := $(TCL_PATH) po/po2msg.sh
+ endif
+ endif
endif
msgsdir = $(gg_libdir)/msgs
$remotes->{$repo_id}->{$_});
}
my $p = $path;
+ my $rwr = rewrite_root({repo_id => $repo_id});
unless (defined $p) {
$p = $full_url;
- $p =~ s#^\Q$u\E(?:/|$)## or next;
+ my $z = $u;
+ if ($rwr) {
+ $z = $rwr;
+ }
+ $p =~ s#^\Q$z\E(?:/|$)## or next;
}
foreach my $f (keys %$fetch) {
next if $f ne $p;
SVN::Client::get_ssl_client_cert_file_provider(),
SVN::Client::get_ssl_client_cert_prompt_provider(
\&Git::SVN::Prompt::ssl_client_cert, 2),
+ SVN::Client::get_ssl_client_cert_pw_file_provider(),
SVN::Client::get_ssl_client_cert_pw_prompt_provider(
\&Git::SVN::Prompt::ssl_client_cert_pw, 2),
SVN::Client::get_username_provider(),
memset(remote_dir_exists, -1, 256);
- http_init();
+ http_init(NULL);
no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
curl_slist_free_all(data->no_pragma_header);
}
-struct walker *get_http_walker(const char *url)
+struct walker *get_http_walker(const char *url, struct remote *remote)
{
char *s;
struct walker_data *data = xmalloc(sizeof(struct walker_data));
struct walker *walker = xmalloc(sizeof(struct walker));
- http_init();
+ http_init(remote);
data->no_pragma_header = curl_slist_append(NULL, "Pragma:");
return result;
}
-void http_init(void)
+void http_init(struct remote *remote)
{
char *low_speed_limit;
char *low_speed_time;
curl_global_init(CURL_GLOBAL_ALL);
+ if (remote && remote->http_proxy)
+ curl_http_proxy = xstrdup(remote->http_proxy);
+
pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache");
#ifdef USE_CURL_MULTI
curl_slist_free_all(pragma_header);
pragma_header = NULL;
+
+ if (curl_http_proxy) {
+ free(curl_http_proxy);
+ curl_http_proxy = NULL;
+ }
}
struct active_request_slot *get_active_slot(void)
#include <curl/easy.h>
#include "strbuf.h"
+#include "remote.h"
/*
* We detect based on the cURL version if multi-transfer is
extern void step_active_slots(void);
#endif
-extern void http_init(void);
+extern void http_init(struct remote *remote);
extern void http_cleanup(void);
extern int data_received;
static const char co_env[] = "GIT_COMMITTER_NAME";
static const char *env_hint =
"\n"
-"*** Your name cannot be determined from your system services (gecos).\n"
+"*** Please tell me who you are.\n"
"\n"
"Run\n"
"\n"
switch (*quoted++) {
case '"':
if (endp)
- *endp = quoted + 1;
+ *endp = quoted;
return 0;
case '\\':
break;
add_pending_object(revs, &head->object, "HEAD");
add_pending_object(revs, &other->object, "MERGE_HEAD");
bases = get_merge_bases(head, other, 1);
- while (bases) {
- struct commit *it = bases->item;
- struct commit_list *n = bases->next;
- free(bases);
- bases = n;
- it->object.flags |= UNINTERESTING;
- add_pending_object(revs, &it->object, "(merge-base)");
- }
+ add_pending_commit_list(revs, bases, UNINTERESTING);
+ free_commit_list(bases);
+ head->object.flags |= SYMMETRIC_LEFT;
if (!active_nr)
read_cache();
i++;
}
revs->prune_data = prune;
+ revs->limited = 1;
}
int handle_revision_arg(const char *arg, struct rev_info *revs,
)
'
+test_expect_success 'check files before directories' '
+
+ echo Notes > release-notes &&
+ git add release-notes &&
+ git commit -m "Add release notes" release-notes &&
+ id=$(git rev-parse HEAD) &&
+ git cvsexportcommit -w "$CVSWORK" -c $id &&
+
+ echo new > DS &&
+ echo new > E/DS &&
+ echo modified > release-notes &&
+ git add DS E/DS release-notes &&
+ git commit -m "Add two files with the same basename" &&
+ id=$(git rev-parse HEAD) &&
+ git cvsexportcommit -w "$CVSWORK" -c $id &&
+ check_entries "$CVSWORK/E" "DS/1.1/|newfile5.txt/1.1/" &&
+ check_entries "$CVSWORK" "DS/1.1/|release-notes/1.2/" &&
+ diff -u "$CVSWORK/DS" DS &&
+ diff -u "$CVSWORK/E/DS" E/DS &&
+ diff -u "$CVSWORK/release-notes" release-notes
+
+'
+
+test_expect_success 'commit a file with leading spaces in the name' '
+
+ echo space > " space" &&
+ git add " space" &&
+ git commit -m "Add a file with a leading space" &&
+ id=$(git rev-parse HEAD) &&
+ git cvsexportcommit -w "$CVSWORK" -c $id &&
+ check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
+ diff -u "$CVSWORK/ space" " space"
+
+'
+
test_done
COMMIT
reset refs/tags/O3-2nd
from :5
+reset refs/tags/O3-3rd
+from :5
INPUT_END
cat >expect <<INPUT_END
# Copyright (c) 2005 Junio C Hamano
#
+# Keep the original TERM for say_color
+ORIGINAL_TERM=$TERM
+
# For repeatability, reset the environment to known value.
LANG=C
LC_ALL=C
PAGER=cat
TZ=UTC
-export LANG LC_ALL PAGER TZ
+TERM=dumb
+export LANG LC_ALL PAGER TERM TZ
EDITOR=:
VISUAL=:
unset GIT_EDITOR
# This test checks if command xyzzy does the right thing...
# '
# . ./test-lib.sh
-
-[ "x$TERM" != "xdumb" ] &&
- [ -t 1 ] &&
- tput bold >/dev/null 2>&1 &&
- tput setaf 1 >/dev/null 2>&1 &&
- tput sgr0 >/dev/null 2>&1 &&
+[ "x$ORIGINAL_TERM" != "xdumb" ] && (
+ TERM=$ORIGINAL_TERM &&
+ export TERM &&
+ [ -t 1 ] &&
+ tput bold >/dev/null 2>&1 &&
+ tput setaf 1 >/dev/null 2>&1 &&
+ tput sgr0 >/dev/null 2>&1
+ ) &&
color=t
while test "$#" -ne 0
if test -n "$color"; then
say_color () {
+ (
+ TERM=$ORIGINAL_TERM
+ export TERM
case "$1" in
error) tput bold; tput setaf 1;; # bold red
skip) tput bold; tput setaf 2;; # bold green
shift
echo "* $*"
tput sgr0
+ )
}
else
say_color() {
struct ref *last_ref = NULL;
if (!transport->data)
- transport->data = get_http_walker(transport->url);
+ transport->data = get_http_walker(transport->url,
+ transport->remote);
refs_url = xmalloc(strlen(transport->url) + 11);
sprintf(refs_url, "%s/info/refs", transport->url);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
curl_easy_setopt(slot->curl, CURLOPT_URL, refs_url);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
- if (transport->remote->http_proxy)
- curl_easy_setopt(slot->curl, CURLOPT_PROXY,
- transport->remote->http_proxy);
if (start_active_slot(slot)) {
run_active_slot(slot);
int nr_objs, struct ref **to_fetch)
{
if (!transport->data)
- transport->data = get_http_walker(transport->url);
+ transport->data = get_http_walker(transport->url,
+ transport->remote);
return fetch_objs_via_walker(transport, nr_objs, to_fetch);
}
#ifndef WALKER_H
#define WALKER_H
+#include "remote.h"
+
struct walker {
void *data;
int (*fetch_ref)(struct walker *, char *ref, unsigned char *sha1);
void walker_free(struct walker *walker);
-struct walker *get_http_walker(const char *url);
+struct walker *get_http_walker(const char *url, struct remote *remote);
#endif /* WALKER_H */