git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Joey Hess <joeyh@joeyh.name>
To: git@vger.kernel.org
Cc: Joey Hess <joeyh@joeyh.name>
Subject: [PATCH v5 8/8] use smudgeToFile filter in recursive merge
Date: Mon, 11 Jul 2016 18:45:12 -0400	[thread overview]
Message-ID: <1468277112-9909-9-git-send-email-joeyh@joeyh.name> (raw)
In-Reply-To: <1468277112-9909-1-git-send-email-joeyh@joeyh.name>

Recursive merge updates the work tree and so should use the smudgeToFile
filter.

At this point, smudgeToFile is run by everything that updates work
tree files.

Signed-off-by: Joey Hess <joeyh@joeyh.name>
---
 merge-recursive.c     | 53 ++++++++++++++++++++++++++++++++++++++++-----------
 t/t0021-conversion.sh | 16 +++++++++++++++-
 2 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index a4a1195..5fe3f50 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -758,6 +758,7 @@ static void update_file_flags(struct merge_options *o,
 		enum object_type type;
 		void *buf;
 		unsigned long size;
+		int isreg;
 
 		if (S_ISGITLINK(mode)) {
 			/*
@@ -774,22 +775,16 @@ static void update_file_flags(struct merge_options *o,
 			die(_("cannot read object %s '%s'"), oid_to_hex(oid), path);
 		if (type != OBJ_BLOB)
 			die(_("blob expected for %s '%s'"), oid_to_hex(oid), path);
-		if (S_ISREG(mode)) {
-			struct strbuf strbuf = STRBUF_INIT;
-			if (convert_to_working_tree(path, buf, size, &strbuf)) {
-				free(buf);
-				size = strbuf.len;
-				buf = strbuf_detach(&strbuf, NULL);
-			}
-		}
 
 		if (make_room_for_path(o, path) < 0) {
 			update_wd = 0;
 			free(buf);
 			goto update_index;
 		}
-		if (S_ISREG(mode) || (!has_symlinks && S_ISLNK(mode))) {
+		isreg = S_ISREG(mode);
+		if (isreg || (!has_symlinks && S_ISLNK(mode))) {
 			int fd;
+			int smudge_to_file;
 			if (mode & 0100)
 				mode = 0777;
 			else
@@ -797,8 +792,44 @@ static void update_file_flags(struct merge_options *o,
 			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
 			if (fd < 0)
 				die_errno(_("failed to open '%s'"), path);
-			write_in_full(fd, buf, size);
-			close(fd);
+
+			smudge_to_file = can_smudge_to_file(path);
+			if (smudge_to_file) {
+				close(fd);
+				fd = convert_to_working_tree_filter_to_file(path, path, buf, size);
+				if (fd < 0) {
+					/*
+					 * smudgeToFile filter failed;
+					 * continue with regular file
+					 * creation.
+					 */
+					smudge_to_file = 0;
+					fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
+					if (fd < 0)
+						die_errno(_("failed to open '%s'"), path);
+				}
+				else {
+					close(fd);
+				}
+			}
+
+			/*
+			 * Not an else of above if (smudge_to_file) because
+			 * the smudgeToFile filter may fail and in that case
+			 * this is run to recover.
+			 */
+			if (!smudge_to_file) {
+				if (isreg) {
+					struct strbuf strbuf = STRBUF_INIT;
+					if (convert_to_working_tree(path, buf, size, &strbuf)) {
+						free(buf);
+						size = strbuf.len;
+						buf = strbuf_detach(&strbuf, NULL);
+					}
+				}
+				write_in_full(fd, buf, size);
+				close(fd);
+			}
 		} else if (S_ISLNK(mode)) {
 			char *lnk = xmemdupz(buf, size);
 			safe_create_leading_directories_const(path);
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index 42b28aa..64b2b8f 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -334,10 +334,24 @@ test_expect_success 'recovery from failure of smudgeToFile filter that deletes t
 	test_cmp test fstest.t
 '
 
+test_expect_success 'smudgeToFile filter is used in merge' '
+	test_config filter.rot13.smudgeToFile ./rot13-to-file.sh &&
+
+	git commit -m "added fstest.t" fstest.t &&
+	git checkout -b old &&
+	git reset --hard HEAD^ &&
+	git merge master &&
+	git checkout master &&
+
+	test -e rot13-to-file.ran &&
+	rm -f rot13-to-file.ran &&
+
+	test_cmp test fstest.t
+'
+
 test_expect_success 'smudgeToFile filter is used by git am' '
 	test_config filter.rot13.smudgeToFile ./rot13-to-file.sh &&
 
-	git commit fstest.t -m "added fstest.t" &&
 	git format-patch HEAD^ --stdout >fstest.patch &&
 	git reset --hard HEAD^ &&
 	git am fstest.patch &&
-- 
2.8.1


  parent reply	other threads:[~2016-07-11 22:47 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-11 22:45 [PATCH v5 0/8] extend smudge/clean filters with direct file access (for pu) Joey Hess
2016-07-11 22:45 ` [PATCH v5 1/8] clarify %f documentation Joey Hess
2016-07-11 22:45 ` [PATCH v5 2/8] add smudgeToFile and cleanFromFile filter configs Joey Hess
2016-07-13 16:02   ` Lars Schneider
2016-07-11 22:45 ` [PATCH v5 3/8] use cleanFromFile in git add Joey Hess
2016-07-11 22:45 ` [PATCH v5 4/8] use smudgeToFile in git checkout etc Joey Hess
2016-07-11 22:45 ` [PATCH v5 5/8] warn on unusable smudgeToFile/cleanFromFile config Joey Hess
2016-07-11 22:45 ` [PATCH v5 6/8] better recovery from failure of smudgeToFile filter Joey Hess
2016-07-11 22:45 ` [PATCH v5 7/8] use smudgeToFile filter in git am Joey Hess
2016-07-11 22:45 ` Joey Hess [this message]
2016-07-12 19:52 ` [PATCH v5 0/8] extend smudge/clean filters with direct file access (for pu) Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1468277112-9909-9-git-send-email-joeyh@joeyh.name \
    --to=joeyh@joeyh.name \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).