aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes-1.5.4.4.txt46
-rw-r--r--Documentation/config.txt8
-rw-r--r--Documentation/git-cherry-pick.txt2
-rw-r--r--Documentation/git-merge.txt3
-rw-r--r--Documentation/git-svn.txt4
-rw-r--r--Documentation/technical/api-diff.txt2
l---------RelNotes2
-rw-r--r--builtin-ls-remote.c4
-rw-r--r--builtin-reflog.c5
-rw-r--r--builtin-revert.c20
-rw-r--r--contrib/emacs/git.el2
-rw-r--r--daemon.c18
-rwxr-xr-xgit-bisect.sh14
-rwxr-xr-xgit-cvsexportcommit.perl51
-rw-r--r--git-gui/Makefile5
-rw-r--r--git-gui/lib/error.tcl2
-rwxr-xr-xgit-merge.sh17
-rwxr-xr-xgit-rebase--interactive.sh4
-rwxr-xr-xgit-send-email.perl9
-rwxr-xr-xgit-submodule.sh2
-rwxr-xr-xgit-svn.perl1
-rw-r--r--http-push.c27
-rw-r--r--http.c14
-rw-r--r--quote.c2
-rw-r--r--receive-pack.c2
-rw-r--r--revision.c12
-rwxr-xr-xt/t2008-checkout-subdir.sh16
-rwxr-xr-xt/t3501-revert-cherry-pick.sh9
-rwxr-xr-xt/t5505-remote.sh3
-rwxr-xr-xt/t6030-bisect-porcelain.sh2
-rwxr-xr-xt/t7600-merge.sh6
-rwxr-xr-xt/t9001-send-email.sh21
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh53
-rw-r--r--t/test-lib.sh41
-rw-r--r--templates/Makefile6
35 files changed, 329 insertions, 106 deletions
diff --git a/Documentation/RelNotes-1.5.4.4.txt b/Documentation/RelNotes-1.5.4.4.txt
new file mode 100644
index 0000000000..5635977c93
--- /dev/null
+++ b/Documentation/RelNotes-1.5.4.4.txt
@@ -0,0 +1,46 @@
+GIT v1.5.4.4 Release Notes
+==========================
+
+Fixes since v1.5.4.3
+--------------------
+
+ * Building and installing with an overtight umask such as 077 made
+ installed templates unreadable by others, while the rest of the install
+ are done in a way that is friendly to umask 022.
+
+ * "git cvsexportcommit -w $cvsdir" misbehaved when GIT_DIR is set to a
+ relative directory.
+
+ * "git http-push" had an invalid memory access that could lead it to
+ segfault.
+
+ * When "git rebase -i" gave control back to the user for a commit that is
+ marked to be edited, it just said "modify it with commit --amend",
+ without saying what to do to continue after modifying it. Give an
+ explicit instruction to run "rebase --continue" to be more helpful.
+
+ * "git send-email" in 1.5.4.3 issued a bogus empty In-Reply-To: header.
+
+ * "git bisect" showed mysterious "won't bisect on seeked tree" error message.
+ This was leftover from Cogito days to prevent "bisect" starting from a
+ cg-seeked state. We still keep the Cogito safety, but running "git bisect
+ start" when another bisect was in effect will clean up and start over.
+
+ * "git push" with an explicit PATH to receive-pack did not quite work if
+ receive-pack was not on usual PATH. We earlier fixed the same issue
+ with "git fetch" and upload-pack, but somehow forgot to do so in the
+ other direction.
+
+ * git-gui's info dialog was not displayed correctly when the user tries
+ to commit nothing (i.e. without staging anything).
+
+ * "git revert" did not properly fail when attempting to run with a
+ dirty index.
+
+Also included are a handful documentation updates.
+
+---
+exec >/var/tmp/1
+echo O=$(git describe maint)
+O=v1.5.4.3-32-g0f2d447
+git shortlog --no-merges $O..maint
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 6d8cca46ab..531ec46e95 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -796,15 +796,15 @@ remote.<name>.skipDefaultUpdate::
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
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 877ab66ef5..f0beb412e6 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -45,7 +45,7 @@ OPTIONS
default is not to do `-x` so this option is a no-op.
-m parent-number|--mainline parent-number::
- Usually you cannot revert a merge because you do not know which
+ Usually you cannot cherry-pick a merge because you do not know which
side of the merge should be considered the mainline. This
option specifies the parent number (starting from 1) of
the mainline and allows cherry-pick to replay the change
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 0c9ad7f2bb..c136b10692 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -68,7 +68,8 @@ HOW MERGE WORKS
---------------
A merge is always between the current `HEAD` and one or more
-remote branch heads, and the index file must exactly match the
+commits (usually, branch head or tag), and the index file must
+exactly match the
tree of `HEAD` commit (i.e. the contents of the last commit) when
it happens. In other words, `git-diff --cached HEAD` must
report no changes.
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index b1d527f74c..115b8bee0d 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -159,6 +159,10 @@ New features:
our version of --pretty=oneline
--
+
+NOTE: SVN itself only stores times in UTC and nothing else. The regular svn
+client converts the UTC time to the local time (or based on the TZ=
+environment). This command has the same behaviour.
++
Any other arguments are passed directly to `git log'
--
diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt
index 83b007e708..20b0241d30 100644
--- a/Documentation/technical/api-diff.txt
+++ b/Documentation/technical/api-diff.txt
@@ -39,7 +39,7 @@ Calling sequence
* Once you finish feeding the pairs of files, call `diffcore_std()`.
This will tell the diffcore library to go ahead and do its work.
-* Calling `diffcore_flush()` will produce the output.
+* Calling `diff_flush()` will produce the output.
Data structures
diff --git a/RelNotes b/RelNotes
index 3084ce6946..f84c4c7f11 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.4.3.txt \ No newline at end of file
+Documentation/RelNotes-1.5.4.4.txt \ No newline at end of file
diff --git a/builtin-ls-remote.c b/builtin-ls-remote.c
index 6dd31d1dd6..720280e390 100644
--- a/builtin-ls-remote.c
+++ b/builtin-ls-remote.c
@@ -94,10 +94,6 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
ref = transport_get_remote_refs(transport);
-
- if (!ref)
- return 1;
-
for ( ; ref; ref = ref->next) {
if (!check_ref_type(ref, flags))
continue;
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 4836ec951b..ab53c8cb7c 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -276,10 +276,11 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
finish:
if (cb.newlog) {
- if (fclose(cb.newlog))
+ if (fclose(cb.newlog)) {
status |= error("%s: %s", strerror(errno),
newlog_path);
- if (rename(newlog_path, log_file)) {
+ unlink(newlog_path);
+ } else if (rename(newlog_path, log_file)) {
status |= error("cannot rename %s to %s",
newlog_path, log_file);
unlink(newlog_path);
diff --git a/builtin-revert.c b/builtin-revert.c
index 358af53747..64f0d0ee02 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -8,6 +8,8 @@
#include "exec_cmd.h"
#include "utf8.h"
#include "parse-options.h"
+#include "diff.h"
+#include "revision.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -245,6 +247,17 @@ static char *help_msg(const unsigned char *sha1)
return helpbuf;
}
+static int index_is_dirty(void)
+{
+ struct rev_info rev;
+ init_revisions(&rev, NULL);
+ setup_revisions(0, NULL, &rev, "HEAD");
+ DIFF_OPT_SET(&rev.diffopt, QUIET);
+ DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
+ run_diff_index(&rev, 1);
+ return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
+}
+
static int revert_or_cherry_pick(int argc, const char **argv)
{
unsigned char head[20];
@@ -273,12 +286,11 @@ static int revert_or_cherry_pick(int argc, const char **argv)
if (write_tree(head, 0, NULL))
die ("Your index file is unmerged.");
} else {
- struct wt_status s;
-
if (get_sha1("HEAD", head))
die ("You do not have a valid HEAD");
- wt_status_prepare(&s);
- if (s.commitable)
+ if (read_cache() < 0)
+ die("could not read the index");
+ if (index_is_dirty())
die ("Dirty index: cannot %s", me);
discard_cache();
}
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index d8a06381f4..0312d891fd 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -1432,7 +1432,7 @@ Commands:
(with-current-buffer buffer
(when (and list-buffers-directory
(string-equal fulldir (expand-file-name list-buffers-directory))
- (string-match "\\*git-status\\*$" (buffer-name buffer)))
+ (eq major-mode 'git-status-mode))
(setq found buffer))))
(setq list (cdr list)))
found))
diff --git a/daemon.c b/daemon.c
index 41a60af624..2b4a6f145c 100644
--- a/daemon.c
+++ b/daemon.c
@@ -1149,6 +1149,11 @@ int main(int argc, char **argv)
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");
@@ -1176,14 +1181,17 @@ int main(int argc, char **argv)
}
}
- 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;
diff --git a/git-bisect.sh b/git-bisect.sh
index 6594a62919..f8857747c4 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -67,16 +67,18 @@ bisect_start() {
die "Bad HEAD - I need a HEAD"
case "$head" in
refs/heads/bisect)
- if [ -s "$GIT_DIR/head-name" ]; then
- branch=`cat "$GIT_DIR/head-name"`
+ if [ -s "$GIT_DIR/BISECT_START" ]; then
+ branch=`cat "$GIT_DIR/BISECT_START"`
else
branch=master
fi
git checkout $branch || exit
;;
refs/heads/*|$_x40)
+ # This error message should only be triggered by cogito usage,
+ # and cogito users should understand it relates to cg-seek.
[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
- echo "${head#refs/heads/}" >"$GIT_DIR/head-name"
+ echo "${head#refs/heads/}" >"$GIT_DIR/BISECT_START"
;;
*)
die "Bad HEAD - strange symbolic ref"
@@ -353,8 +355,8 @@ bisect_reset() {
return
}
case "$#" in
- 0) if [ -s "$GIT_DIR/head-name" ]; then
- branch=`cat "$GIT_DIR/head-name"`
+ 0) if [ -s "$GIT_DIR/BISECT_START" ]; then
+ branch=`cat "$GIT_DIR/BISECT_START"`
else
branch=master
fi ;;
@@ -365,7 +367,9 @@ bisect_reset() {
usage ;;
esac
if git checkout "$branch"; then
+ # Cleanup head-name if it got left by an old version of git-bisect
rm -f "$GIT_DIR/head-name"
+ rm -f "$GIT_DIR/BISECT_START"
bisect_clean_state
fi
}
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index d2e50c3429..b6036bd4d3 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -5,6 +5,7 @@ use Getopt::Std;
use File::Temp qw(tempdir);
use Data::Dumper;
use File::Basename qw(basename dirname);
+use File::Spec;
our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w);
@@ -15,17 +16,15 @@ $opt_h && usage();
die "Need at least one commit identifier!" unless @ARGV;
if ($opt_w) {
+ # Remember where GIT_DIR is before changing to CVS checkout
unless ($ENV{GIT_DIR}) {
- # Remember where our GIT_DIR is before changing to CVS checkout
+ # No GIT_DIR set. Figure it out for ourselves
my $gd =`git-rev-parse --git-dir`;
chomp($gd);
- if ($gd eq '.git') {
- my $wd = `pwd`;
- chomp($wd);
- $gd = $wd."/.git" ;
- }
$ENV{GIT_DIR} = $gd;
}
+ # Make sure GIT_DIR is absolute
+ $ENV{GIT_DIR} = File::Spec->rel2abs($ENV{GIT_DIR});
if (! -d $opt_w."/CVS" ) {
die "$opt_w is not a CVS checkout";
@@ -198,15 +197,39 @@ if (@canstatusfiles) {
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;
+ }
+ }
+ }
}
}
diff --git a/git-gui/Makefile b/git-gui/Makefile
index 01e0a46ba5..4e321742ab 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -224,6 +224,11 @@ else
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
diff --git a/git-gui/lib/error.tcl b/git-gui/lib/error.tcl
index 08a24622c7..8c27678e3a 100644
--- a/git-gui/lib/error.tcl
+++ b/git-gui/lib/error.tcl
@@ -47,7 +47,7 @@ proc info_popup {msg} {
append title " ([reponame])"
}
tk_messageBox \
- -parent $parent \
+ -parent [_error_parent] \
-icon info \
-type ok \
-title $title \
diff --git a/git-merge.sh b/git-merge.sh
index 1c123a37e6..03cd39873a 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -37,6 +37,7 @@ use_strategies=
allow_fast_forward=t
allow_trivial_merge=t
+squash= no_commit=
dropsave() {
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
@@ -152,17 +153,21 @@ parse_config () {
--summary)
show_diffstat=t ;;
--squash)
- allow_fast_forward=t squash=t no_commit=t ;;
+ test "$allow_fast_forward" = t ||
+ die "You cannot combine --squash with --no-ff."
+ squash=t no_commit=t ;;
--no-squash)
- allow_fast_forward=t squash= no_commit= ;;
+ squash= no_commit= ;;
--commit)
- allow_fast_forward=t squash= no_commit= ;;
+ no_commit= ;;
--no-commit)
- allow_fast_forward=t squash= no_commit=t ;;
+ no_commit=t ;;
--ff)
- allow_fast_forward=t squash= no_commit= ;;
+ allow_fast_forward=t ;;
--no-ff)
- allow_fast_forward=false squash= no_commit= ;;
+ test "$squash" != t ||
+ die "You cannot combine --squash with --no-ff."
+ allow_fast_forward=f ;;
-s|--strategy)
shift
case " $all_strategies " in
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index fb12b03b20..c2bedd622c 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -268,6 +268,10 @@ do_next () {
warn
warn " git commit --amend"
warn
+ warn "Once you are satisfied with your changes, run"
+ warn
+ warn " git rebase --continue"
+ warn
exit 0
;;
squash|s)
diff --git a/git-send-email.perl b/git-send-email.perl
index 8e6f3b22c8..e5d67f1b6c 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -166,7 +166,9 @@ my $envelope_sender;
my $repo = Git->repository();
my $term = eval {
- new Term::ReadLine 'git-send-email';
+ $ENV{"GIT_SEND_EMAIL_NOTTY"}
+ ? new Term::ReadLine 'git-send-email', \*STDIN, \*STDOUT
+ : new Term::ReadLine 'git-send-email';
};
if ($@) {
$term = new FakeTerm "$@: going non-interactive";
@@ -407,8 +409,9 @@ if ($thread && !defined $initial_reply_to && $prompting) {
$initial_reply_to = $_;
}
if (defined $initial_reply_to) {
- $initial_reply_to =~ s/^\s*<?/</;
- $initial_reply_to =~ s/>?\s*$/>/;
+ $initial_reply_to =~ s/^\s*<?//;
+ $initial_reply_to =~ s/>?\s*$//;
+ $initial_reply_to = "<$initial_reply_to>" if $initial_reply_to ne '';
}
if (!defined $smtp_server) {
diff --git a/git-submodule.sh b/git-submodule.sh
index a6aaf40b0a..67d3224c8c 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -362,7 +362,7 @@ cmd_status()
do
name=$(module_name "$path") || exit
url=$(git config submodule."$name".url)
- if test -z "url" || ! test -d "$path"/.git
+ if test -z "$url" || ! test -d "$path"/.git
then
say "-$sha1 $path"
continue;
diff --git a/git-svn.perl b/git-svn.perl
index 75e97cc72f..a4ab05155d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3632,6 +3632,7 @@ sub _auth_providers () {
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(),
diff --git a/http-push.c b/http-push.c
index 869c01c75b..e3e34decd2 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1634,12 +1634,19 @@ static struct object_list **process_tree(struct tree *tree,
init_tree_desc(&desc, tree->buffer, tree->size);
- while (tree_entry(&desc, &entry)) {
- if (S_ISDIR(entry.mode))
+ while (tree_entry(&desc, &entry))
+ switch (object_type(entry.mode)) {
+ case OBJ_TREE:
p = process_tree(lookup_tree(entry.sha1), p, &me, name);
- else
+ break;
+ case OBJ_BLOB:
p = process_blob(lookup_blob(entry.sha1), p, &me, name);
- }
+ break;
+ default:
+ /* Subproject commit - not in this repository */
+ break;
+ }
+
free(tree->buffer);
tree->buffer = NULL;
return p;
@@ -2398,15 +2405,17 @@ int main(int argc, char **argv)
fill_active_slots();
add_fill_function(NULL, fill_active_slot);
#endif
- finish_all_active_slots();
+ do {
+ finish_all_active_slots();
+#ifdef USE_CURL_MULTI
+ fill_active_slots();
+#endif
+ } while (request_queue_head && !aborted);
/* Update the remote branch if all went well */
- if (aborted || !update_remote(ref->new_sha1, ref_lock)) {
+ if (aborted || !update_remote(ref->new_sha1, ref_lock))
rc = 1;
- goto unlock;
- }
- unlock:
if (!rc)
fprintf(stderr, " done\n");
unlock_remote(ref_lock);
diff --git a/http.c b/http.c
index 8e554c0969..256a5f15f4 100644
--- a/http.c
+++ b/http.c
@@ -284,23 +284,15 @@ void http_init(struct remote *remote)
void http_cleanup(void)
{
struct active_request_slot *slot = active_queue_head;
-#ifdef USE_CURL_MULTI
- char *wait_url;
-#endif
while (slot != NULL) {
struct active_request_slot *next = slot->next;
+ if (slot->curl != NULL) {
#ifdef USE_CURL_MULTI
- if (slot->in_use) {
- curl_easy_getinfo(slot->curl,
- CURLINFO_EFFECTIVE_URL,
- &wait_url);
- fprintf(stderr, "Waiting for %s\n", wait_url);
- run_active_slot(slot);
- }
+ curl_multi_remove_handle(curlm, slot->curl);
#endif
- if (slot->curl != NULL)
curl_easy_cleanup(slot->curl);
+ }
free(slot);
slot = next;
}
diff --git a/quote.c b/quote.c
index d061626c34..40702f6b72 100644
--- a/quote.c
+++ b/quote.c
@@ -288,7 +288,7 @@ int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
switch (*quoted++) {
case '"':
if (endp)
- *endp = quoted + 1;
+ *endp = quoted;
return 0;
case '\\':
break;
diff --git a/receive-pack.c b/receive-pack.c
index 3267495832..c90ec7dde2 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -469,6 +469,8 @@ int main(int argc, char **argv)
if (!dir)
usage(receive_pack_usage);
+ setup_path(NULL);
+
if (!enter_repo(dir, 0))
die("'%s': unable to chdir or not a git archive", dir);
diff --git a/revision.c b/revision.c
index 6e85aaa3fb..a399f27144 100644
--- a/revision.c
+++ b/revision.c
@@ -749,14 +749,9 @@ static void prepare_show_merge(struct rev_info *revs)
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();
@@ -775,6 +770,7 @@ static void prepare_show_merge(struct rev_info *revs)
i++;
}
revs->prune_data = prune;
+ revs->limited = 1;
}
int handle_revision_arg(const char *arg, struct rev_info *revs,
diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh
index f78945ed8e..3e098ab31e 100755
--- a/t/t2008-checkout-subdir.sh
+++ b/t/t2008-checkout-subdir.sh
@@ -67,16 +67,16 @@ test_expect_success 'checkout with simple prefix' '
'
-test_expect_failure 'relative path outside tree should fail' \
- 'git checkout HEAD -- ../../Makefile'
+test_expect_success 'relative path outside tree should fail' \
+ 'test_must_fail git checkout HEAD -- ../../Makefile'
-test_expect_failure 'incorrect relative path to file should fail (1)' \
- 'git checkout HEAD -- ../file0'
+test_expect_success 'incorrect relative path to file should fail (1)' \
+ 'test_must_fail git checkout HEAD -- ../file0'
-test_expect_failure 'incorrect relative path should fail (2)' \
- '( cd dir1 && git checkout HEAD -- ./file0 )'
+test_expect_success 'incorrect relative path should fail (2)' \
+ '( cd dir1 && test_must_fail git checkout HEAD -- ./file0 )'
-test_expect_failure 'incorrect relative path should fail (3)' \
- '( cd dir1 && git checkout HEAD -- ../../file0 )'
+test_expect_success 'incorrect relative path should fail (3)' \
+ '( cd dir1 && test_must_fail git checkout HEAD -- ../../file0 )'
test_done
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 2dbe04fb20..6da212825a 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -59,4 +59,13 @@ test_expect_success 'revert after renaming branch' '
'
+test_expect_success 'revert forbidden on dirty working tree' '
+
+ echo content >extra_file &&
+ git add extra_file &&
+ test_must_fail git revert HEAD 2>errors &&
+ grep "Dirty index" errors
+
+'
+
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 636aec2f71..4fc62f550c 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -4,9 +4,6 @@ test_description='git remote porcelain-ish'
. ./test-lib.sh
-GIT_CONFIG=.git/config
-export GIT_CONFIG
-
setup_repository () {
mkdir "$1" && (
cd "$1" &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index ec71123f4b..4908e878fe 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -260,7 +260,7 @@ test_expect_success 'bisect starting with a detached HEAD' '
git checkout master^ &&
HEAD=$(git rev-parse --verify HEAD) &&
git bisect start &&
- test $HEAD = $(cat .git/head-name) &&
+ test $HEAD = $(cat .git/BISECT_START) &&
git bisect reset &&
test $HEAD = $(git rev-parse --verify HEAD)
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 50c51c82fa..5d166280cb 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -419,6 +419,7 @@ test_debug 'gitk --all'
test_expect_success 'merge c0 with c1 (no-ff)' '
git reset --hard c0 &&
+ git config branch.master.mergeoptions "" &&
test_tick &&
git merge --no-ff c1 &&
verify_merge file result.1 &&
@@ -427,6 +428,11 @@ test_expect_success 'merge c0 with c1 (no-ff)' '
test_debug 'gitk --all'
+test_expect_success 'combining --squash and --no-ff is refused' '
+ test_must_fail git merge --squash --no-ff c1 &&
+ test_must_fail git merge --no-ff --squash c1
+'
+
test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '
git reset --hard c0 &&
git config branch.master.mergeoptions "--no-ff" &&
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 08f7c3d8d7..2efaed441d 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -108,4 +108,25 @@ test_expect_success 'allow long lines with --no-validate' '
2>errors
'
+test_expect_success 'Invalid In-Reply-To' '
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --in-reply-to=" " \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches
+ 2>errors
+ ! grep "^In-Reply-To: < *>" msgtxt
+'
+
+test_expect_success 'Valid In-Reply-To when prompting' '
+ (echo "From Example <from@example.com>"
+ echo "To Example <to@example.com>"
+ echo ""
+ ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches 2>errors &&
+ ! grep "^In-Reply-To: < *>" msgtxt
+'
+
test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index a15222ced4..58c59ed5ae 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -2,7 +2,7 @@
#
# Copyright (c) Robin Rosenberg
#
-test_description='CVS export comit. '
+test_description='Test export of commits to CVS'
. ./test-lib.sh
@@ -246,4 +246,55 @@ test_expect_success \
;;
esac
+test_expect_success '-w option should work with relative GIT_DIR' '
+ mkdir W &&
+ echo foobar >W/file1.txt &&
+ echo bazzle >W/file2.txt &&
+ git add W/file1.txt &&
+ git add W/file2.txt &&
+ git commit -m "More updates" &&
+ id=$(git rev-list --max-count=1 HEAD) &&
+ (cd "$GIT_DIR" &&
+ GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id &&
+ check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" &&
+ diff -u "$CVSWORK/W/file1.txt" ../W/file1.txt &&
+ diff -u "$CVSWORK/W/file2.txt" ../W/file2.txt
+ )
+'
+
+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
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 142540e1b1..44f5776a1b 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -3,12 +3,16 @@
# 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
@@ -58,12 +62,14 @@ esac
# 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
@@ -91,6 +97,9 @@ done
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
@@ -101,6 +110,7 @@ if test -n "$color"; then
shift
echo "* $*"
tput sgr0
+ )
}
else
say_color() {
@@ -257,6 +267,23 @@ test_expect_code () {
echo >&3 ""
}
+# This is not among top-level (test_expect_success | test_expect_failure)
+# but is a prefix that can be used in the test script, like:
+#
+# test_expect_success 'complain and die' '
+# do something &&
+# do something else &&
+# test_must_fail git checkout ../outerspace
+# '
+#
+# Writing this as "! git checkout ../outerspace" is wrong, because
+# the failure could be due to a segv. We want a controlled failure.
+
+test_must_fail () {
+ "$@"
+ test $? -gt 0 -a $? -le 128
+}
+
# Most tests can use the created repository, but some may need to create more.
# Usage: test_create_repo <directory>
test_create_repo () {
diff --git a/templates/Makefile b/templates/Makefile
index ebd3a62fd8..bda9d13505 100644
--- a/templates/Makefile
+++ b/templates/Makefile
@@ -29,10 +29,10 @@ boilerplates.made : $(bpsrc)
case "$$boilerplate" in *~) continue ;; esac && \
dst=`echo "$$boilerplate" | sed -e 's|^this|.|;s|--|/|g'` && \
dir=`expr "$$dst" : '\(.*\)/'` && \
- mkdir -p blt/$$dir && \
+ $(INSTALL) -d -m 755 blt/$$dir && \
case "$$boilerplate" in \
*--) ;; \
- *) cp $$boilerplate blt/$$dst ;; \
+ *) cp -p $$boilerplate blt/$$dst ;; \
esac || exit; \
done && \
date >$@
@@ -48,4 +48,4 @@ clean:
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_dir_SQ)'
(cd blt && $(TAR) cf - .) | \
- (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && $(TAR) xf -)
+ (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && umask 022 && $(TAR) xf -)