From 995fc2f7e17fab8dd59f31f25870a0823cdb6f27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kr=C3=BCger?= <jk@jk.gs>
Date: Fri, 27 Nov 2009 08:17:05 -0600
Subject: [PATCH 1/2] pull: clarify advice for the unconfigured error case
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When pull --rebase fails because it cannot find what branch to
merge against, the error message implies we are trying to merge.
Say "rebase against" instead of "merge with" to avoid confusion.

The configuration suggested to remedy the situation uses a
confusing syntax, with variables specified in the dotted form
accepted by 'git config' but separated from their values by the
'=' delimiter used by config files.  Since the user will have to
edit this output anyway, it is more helpful to provide a config
file snippet to paste into an editor and modify.

Signed-off-by: Jan Krüger <jk@jk.gs>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-pull.sh | 48 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/git-pull.sh b/git-pull.sh
index fc78592ae0..2530f21861 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -88,45 +88,63 @@ error_on_no_merge_candidates () {
 		esac
 	done
 
+	if test true = "$rebase"
+	then
+		op_type=rebase
+		op_prep=against
+	else
+		op_type=merge
+		op_prep=with
+	fi
+
 	curr_branch=${curr_branch#refs/heads/}
 	upstream=$(git config "branch.$curr_branch.merge")
 	remote=$(git config "branch.$curr_branch.remote")
 
 	if [ $# -gt 1 ]; then
-		echo "There are no candidates for merging in the refs that you just fetched."
+		if [ "$rebase" = true ]; then
+			printf "There is no candidate for rebasing against "
+		else
+			printf "There are no candidates for merging "
+		fi
+		echo "among the refs that you just fetched."
 		echo "Generally this means that you provided a wildcard refspec which had no"
 		echo "matches on the remote end."
 	elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
 		echo "You asked to pull from the remote '$1', but did not specify"
-		echo "a branch to merge. Because this is not the default configured remote"
+		echo "a branch. Because this is not the default configured remote"
 		echo "for your current branch, you must specify a branch on the command line."
 	elif [ -z "$curr_branch" ]; then
 		echo "You are not currently on a branch, so I cannot use any"
 		echo "'branch.<branchname>.merge' in your configuration file."
-		echo "Please specify which branch you want to merge on the command"
+		echo "Please specify which remote branch you want to use on the command"
 		echo "line and try again (e.g. 'git pull <repository> <refspec>')."
 		echo "See git-pull(1) for details."
 	elif [ -z "$upstream" ]; then
 		echo "You asked me to pull without telling me which branch you"
-		echo "want to merge with, and 'branch.${curr_branch}.merge' in"
-		echo "your configuration file does not tell me either.	Please"
-		echo "specify which branch you want to merge on the command line and"
+		echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
+		echo "your configuration file does not tell me, either. Please"
+		echo "specify which branch you want to use on the command line and"
 		echo "try again (e.g. 'git pull <repository> <refspec>')."
 		echo "See git-pull(1) for details."
 		echo
-		echo "If you often merge with the same branch, you may want to"
-		echo "configure the following variables in your configuration"
-		echo "file:"
+		echo "If you often $op_type $op_prep the same branch, you may want to"
+		echo "use something like the following in your configuration file:"
 		echo
-		echo "    branch.${curr_branch}.remote = <nickname>"
-		echo "    branch.${curr_branch}.merge = <remote-ref>"
-		echo "    remote.<nickname>.url = <url>"
-		echo "    remote.<nickname>.fetch = <refspec>"
+		echo "    [branch \"${curr_branch}\"]"
+		echo "    remote = <nickname>"
+		echo "    merge = <remote-ref>"
+		test rebase = "$op_type" &&
+			echo "    rebase = true"
+		echo
+		echo "    [remote \"<nickname>\"]"
+		echo "    url = <url>"
+		echo "    fetch = <refspec>"
 		echo
 		echo "See git-config(1) for details."
 	else
-		echo "Your configuration specifies to merge the ref '${upstream#refs/heads/}' from the"
-		echo "remote, but no such ref was fetched."
+		echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
+		echo "from the remote, but no such ref was fetched."
 	fi
 	exit 1
 }

From 8947fdd598848b8ceb2cea9ff42e906c946eae5c Mon Sep 17 00:00:00 2001
From: Jeff King <peff@peff.net>
Date: Tue, 8 Dec 2009 02:49:35 -0500
Subject: [PATCH 2/2] add-interactive: fix deletion of non-empty files

Commit 24ab81a fixed the deletion of empty files, but broke
deletion of non-empty files. The approach it took was to
factor out the "deleted" line from the patch header into its
own hunk, the same way we do for mode changes. However,
unlike mode changes, we only showed the special "delete this
file" hunk if there were no other hunks. Otherwise, the user
would annoyingly be presented with _two_ hunks: one for
deleting the file and one for deleting the content.

This meant that in the non-empty case, we forgot about the
deleted line entirely, and we submitted a bogus patch to
git-apply (with "/dev/null" as the destination file, but not
marked as a deletion).

Instead, this patch combines the file deletion hunk and the
content deletion hunk (if there is one) into a single
deletion hunk which is either staged or not.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-add--interactive.perl  |  6 +++++-
 t/t3701-add-interactive.sh | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 35f4ef11de..02e97b90f1 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -1217,7 +1217,11 @@ sub patch_update_file {
 	if (@{$mode->{TEXT}}) {
 		unshift @hunk, $mode;
 	}
-	if (@{$deletion->{TEXT}} && !@hunk) {
+	if (@{$deletion->{TEXT}}) {
+		foreach my $hunk (@hunk) {
+			push @{$deletion->{TEXT}}, @{$hunk->{TEXT}};
+			push @{$deletion->{DISPLAY}}, @{$hunk->{DISPLAY}};
+		}
 		@hunk = ($deletion);
 	}
 
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index aa5909b14c..0926b91d57 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -214,6 +214,26 @@ test_expect_success 'add first line works' '
 	test_cmp expected diff
 '
 
+cat >expected <<EOF
+diff --git a/non-empty b/non-empty
+deleted file mode 100644
+index d95f3ad..0000000
+--- a/non-empty
++++ /dev/null
+@@ -1 +0,0 @@
+-content
+EOF
+test_expect_success 'deleting a non-empty file' '
+	git reset --hard &&
+	echo content >non-empty &&
+	git add non-empty &&
+	git commit -m non-empty &&
+	rm non-empty &&
+	echo y | git add -p non-empty &&
+	git diff --cached >diff &&
+	test_cmp expected diff
+'
+
 cat >expected <<EOF
 diff --git a/empty b/empty
 deleted file mode 100644