From patchwork Sun May 5 10:19:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13654230 Received: from mout.web.de (mout.web.de [212.227.17.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D74B4B674 for ; Sun, 5 May 2024 10:20:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714904407; cv=none; b=HvE38PIFx30+VCO7XBKZQm6BRAU/HwqTo0LUfIBB+HEwdvpvdUVp0NVh4QHfvpPqDrmeU26Y27IVUyzydRnwZPh7fVgvSZK05CRCzpmgnRvUErZPA+PlToj8600TiM7ZexAtqg1yjc5PQII9EMN2MPG2G5nWDsf9ggbhdAKqAH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714904407; c=relaxed/simple; bh=F3lwT5vzDo5DAoORjs7W/h6EUVoQ+pHygIbH8qvDqxQ=; h=Message-ID:Date:MIME-Version:Subject:From:To:References:Cc: In-Reply-To:Content-Type; b=Sbpzi5wXfR/Q1pUS9Di4TkskUHKcM8bvXku9piEPwihD/VE2k+G9m54TfF23McawWf6v44BEFrZpjcSyq+3CD1QL2384/lZ3pWhAX/Oz3hZKgaGdIz8coCqICT1im0PvyAUaYAxFd80xuWcIkqBy1Edfm832Qh1anXj9yjBkbPA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=DgrSeLAA; arc=none smtp.client-ip=212.227.17.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="DgrSeLAA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1714904397; x=1715509197; i=l.s.r@web.de; bh=3QS3zchuBaFQ9GMVy3pA5IFCg9fNc/V9H1mcagxnVUM=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: References:Cc:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=DgrSeLAAFkCxxnG+XEEVgTdAYBo11GVOVKFhZUY7nkKfPddHND42li3dHOi5QNKu CepNjlFuBoqwFkjkYtlfMt1uEqIvl+T/NyqxuolMAZIZqA7vJ09OR5wM0cGC6SSh3 +fDqcTzufilxTyubeLraSBxnZRQyF2i2TDdhFZCDejVtpVfenhU4kqUEBfsQo3hPM 4EkDLDKz6Y11ISmIKWDIhfsijNT7N+Mru1srnu4HFt5GmhjKyFZNPHOUapN6rQGh5 qarQ1EFcCLKnptgVqfx7vVrBrVYMWzrOOR1ue0iMDhFfX5BwvN9JTOUrJ56aq1eHQ i8IfX1PniKRGeory7A== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.153.5]) by smtp.web.de (mrweb106 [213.165.67.124]) with ESMTPSA (Nemesis) id 1M5j5k-1s0n1L1cEc-007AGL; Sun, 05 May 2024 12:19:57 +0200 Message-ID: Date: Sun, 5 May 2024 12:19:56 +0200 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 1/2] diff: report unmerged paths as changes in run_diff_cmd() From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: German Lashevich , git@vger.kernel.org References: <82561c70-ec33-41bf-b036-52310ffc1926@web.de> Content-Language: en-US Cc: Junio C Hamano In-Reply-To: <82561c70-ec33-41bf-b036-52310ffc1926@web.de> X-Provags-ID: V03:K1:v+KvzftgEy0tzyJWuzMLmBHTT/sGveK3IpjougB+X7XtwDPPQJo fJJJPaiyZ7ZKbirZlkFRTNW95LVJpKt4Os/jTIsTEnJJRyU2MHqaJxUAYyP4LvJxeUePnnC o0keVvxKQJMML52RpnR4EFx1iySAY3r8YQaV3CM2avTUeRpBxlrhhfPFdQzF5T4gKm7l+4M BOmpZDjD+7QTAsmocBIlw== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:jqJiqjQxRMI=;Bg7MXLhUtnDZP2MMVM3o9HOjHNp gIYZ9nJU7B77P5lvL7To1ud3k9hK6y0JSQDFK0E9HraX1tEqDaRkA53uGaM+Z5XKKWKXlUjob eAK7xByCcLlOSAS8aTjvNEmJ4euM1a+dCUwgXqgds6DRKiLamXRmL/V68kOSeqLj9zCGWK7Na popGDYgzWnrhSauIyFlhYa3OthKcha0RSob2mOvhxZBoDlC+bN9D3ZFr0w7jReA5jge0QcPE5 IoL2SV+KUh7ZFEWUmobEhQBc9/IsGd5uWJq9T88gQeW7oKQWbuj0EnshORbrVnmllf0CEzEIy FObgqjeZOAyr8ADzhpZ4s3Gh1nVPrQcPXN5Z3mzHbw/ISid/t4dy84rlNs9REjhhuwG6T2wTj bSPggUYipPW+TG32iXENkXXxrZR+ZCGJlX+AETU1VMhCp9Tl+27LC7aaVXE9BHPSCVzW7yf39 zzyh4laQY1+Uj1I6hh5LZAR8aDpX+dokqzJf+8xrOUcli9IbCmhEB2mWgOep0+oFWJ6yTHnUB N+9NBCoVJwXtq/7TUIfeD8KUKaNV7J7DGcoivoGGFbMZx3GZpqgyQZzDTI6YMEfcj+ipX6l8G BA8lyGiZNLwt0IycuTdUFJphY9jzS8Rg+UZybma6p/0JKSHF6AufP35y3tuaiSsOy6+igF2bB AiCEIFd0m0XEBpeyqcBCDx6odS+LGS4od4cW2G6PX3hk3BnXPVqyZLm3HegeMQNZAC4TBO0cA w4RbbztT/5N+h6kGZgSbwgNVO8cUasIVt07Mdx8N+OTJ3pbFA9AflsX3PLjj2sU6ixdOOf/og CFKNLnXfMO3ACSCNdWiAEIm4yyifEhGFoOLEKdE+mdCg0= You can ask the diff machinery to let the exit code indicate whether there are changes, e.g. with --quiet. It as two ways to calculate that bit: The quick one assumes blobs with different hashes have different content, and the more elaborate way actually compares the contents, possibly applying transformations like ignoring whitespace. The quick way considers an unmerged file to be a change and reports exit code 1, which makes sense. The slower path uses the struct diff_options member found_changes to indicate whether the blobs differ even with the transformations applied. It's not set for unmerged files, though, resulting in exit code 0. Set found_changes in run_diff_cmd() for unmerged files, for a consistent exit code of 1 if there's an unmerged file, regardless of whether whitespace is ignored. Signed-off-by: René Scharfe --- diff.c | 1 + t/t4046-diff-unmerged.sh | 8 ++++++++ 2 files changed, 9 insertions(+) -- 2.45.0 diff --git a/diff.c b/diff.c index 108c187577..ded9ac70df 100644 --- a/diff.c +++ b/diff.c @@ -4555,6 +4555,7 @@ static void run_diff_cmd(const char *pgm, o, complete_rewrite); } else { fprintf(o->file, "* Unmerged path %s\n", name); + o->found_changes = 1; } } diff --git a/t/t4046-diff-unmerged.sh b/t/t4046-diff-unmerged.sh index ffaf69335f..c606ee4c40 100755 --- a/t/t4046-diff-unmerged.sh +++ b/t/t4046-diff-unmerged.sh @@ -96,4 +96,12 @@ test_expect_success 'diff --stat' ' test_cmp diff-stat.expect diff-stat.actual ' +test_expect_success 'diff --quiet' ' + test_expect_code 1 git diff --cached --quiet +' + +test_expect_success 'diff --quiet --ignore-all-space' ' + test_expect_code 1 git diff --cached --quiet --ignore-all-space +' + test_done From patchwork Sun May 5 10:20:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13654231 Received: from mout.web.de (mout.web.de [217.72.192.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DBFB79FE for ; Sun, 5 May 2024 10:20:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.72.192.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714904412; cv=none; b=JXUZvVLVcHGBd+rkbkFa4Yf9SqWgOw/guevB5NbTchYrry20T8vT335KtX1Rwl1QNSNtOH9E5z+VAzSkg5GennDMzSidGSRWlG9yVfmb+ScgpJuDPpZHD1e3CQzXQMlxCL6WmqV90csrRRq2Vq+reRgnyTVx+o3k1kKBuDn+nzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714904412; c=relaxed/simple; bh=KXnhGCTuZRywWGms28GUaOLyMSZgvFGwTEUx7BwZXw4=; h=Message-ID:Date:MIME-Version:Subject:From:To:References:Cc: In-Reply-To:Content-Type; b=ShsQnYCfj6qcgCVxJkjLcUS7j6GgyC9Bfd2CLV2vVoHI1qRBPEA1spk0YeAzwqMKlXWwg5hAQSYoZR4wVzPDvmTMtb/1jzGxMWWKyL+9WAzJagQ0/fKulI7Cb+V3mvYGHJIq7uyMcx2Q9zF3tsKxKOtHvTGgvCZYEsayTvzcNfA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=BZBEfWg1; arc=none smtp.client-ip=217.72.192.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="BZBEfWg1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1714904404; x=1715509204; i=l.s.r@web.de; bh=E9iD3qnHno0Pajvq0t4EX+K97QFhtTpFVaF0X2euRQo=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: References:Cc:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=BZBEfWg1a37c3UsKjfW48NqFOA239LLmMBhFjyDFvg8f8Lu7HUo5OK3fYmm+6xiS 0lxjIHqBuELntH8YTBC3jdlwTGyiYizdkBuFrRiNF8XWesJo/Ps0p9ltDzf40Y6M3 vEIgQXphMiNM5ulX041g5Z7vwedpIQ/zE5288cOajTOwHKB7LUjlR+gXFZ6VTN7uk TkHeZWyZiY9HU/PcpZTZc7ScSxDlkDAz3AgWZXMHEf5SltxWdxK/Ib3s/vKHIPa/l FtaQ3OF6V40du2WmwU5EOdwtmojM7g6Sxu1rD2cT8M7rujTDli6MkU+rOG8C3NjaE zgz1ykkNgWryDGFwug== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.153.5]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1MKMA1-1sLM8x0EwB-00KBnw; Sun, 05 May 2024 12:20:04 +0200 Message-ID: Date: Sun, 5 May 2024 12:20:03 +0200 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 2/2] diff: fix --exit-code with external diff From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: German Lashevich , git@vger.kernel.org References: <82561c70-ec33-41bf-b036-52310ffc1926@web.de> Content-Language: en-US Cc: Junio C Hamano In-Reply-To: <82561c70-ec33-41bf-b036-52310ffc1926@web.de> X-Provags-ID: V03:K1:kVcGjChM3+388TEegDsebmzCiMaKZCQGGVcICo/mfIWa6U2QAyi KmDEeL2OEtXD3f0geJ4zoTdyqFl/Fzu2cQzBg7o5F8Px7I0aBLRwR2M8+c9I2gW8lLZnQLG MwwqO1F32WE4zGdr6Sa5YqRdUwJMiASdAlFlpC64vtLDKd/fPpluSr4W7wQ+0QoiUhmaRWf Cv9ztdvH9O2hembEIt3Jw== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:ws2yJqjiZ1c=;knThAzhcjpSukBhhcpwwPxGBEVf MsOIBQaDmXRoq6IlmznAuF1vCRjq+1sLX8AcVMCBXZzEWW9ac71paCXTzHSM2y6nk+7ZQtSs9 kYaPbUL4VtkIBr3CuHZPLcffTws2jusjXj4K/nu0NMWzWA5NZUQ8OLuPSU7IAxR2N+2inmnbk HhVArlqTKQIH/2d7bqlxM5sy/y4Edm+QBdc1kgrSlnY6W1cuj3FI/wUNQ+GUc5T648d9S14Kx y3exeYUnHN3dNXnPpJlX+euu6XT+Iymp73wWuxg/zkm2dPf4cjC02q6KQ80gRWdV14riddGdb Oiz1+BFggmiJ2q92l297Svcnf12hv9u1BOQNRr+qrSykJ8XtDY4e/8jpRg1r+trmrZEzHCAE2 TyxF+j/GewQnwher0/qmByh3rBeiYQA9r79OxWZq4W/q6TUW2bKU0T+zneofinABn/MAXs/qw k8+LCqAB67RnSlSUdzflVxLxktmnZ6+eNJmL/Vf4hfWmBMFHc/6SCiXWj8PD5Qp0HeDq5JMiB 0+bg2IUZnEldy52wWe/Hgu3clMxFzMESSdO5fbwKIX6vpBPklBRSPU4HDicqsEXJFkkDIRG4O oCOMHRRfcmBe2q2WSnGId41bVe6vYopQ9plAY7rYXslrSedyPTcI2oiy9PtKjII51JdMZ65xB vMsVdlz/0Rh9og3N9bUB6fRpCakXJSVO7TQQc48PL/W98+yWPe/71cXeoYZTOaaA4SJluJSOA LG+jtNM8xhnKg6AW8Y4RXBUKMis+8ulBq5tlodyNT9Nl2qV1zfdG7RxBG2xl1IKCAG1spDP5k jfuc8AO3gvLOgWN2FMK7cj4ZFpeIybg3qp3/ixcPkDgSM= You can ask the diff machinery to let the exit code indicate whether there are changes, e.g. with --exit-code. It as two ways to calculate that bit: The quick one assumes blobs with different hashes have different content, and the more elaborate way actually compares the contents, possibly applying transformations like ignoring whitespace. Always use the slower path by setting the flag diff_from_contents, because any of the files could have an external diff driver set via an attribute, which might consider binary differences irrelevant, like e.g. --- 2.45.0 diff -b. And don't stop walking that path in diff_flush() just because output_format is unset. Instead run diff_flush_patch() with output redirected to /dev/null to get the exit status, like we already do for DIFF_FORMAT_NO_OUTPUT. That's consistent with the comments in diff.h: /* Same as output_format = 0 but we know that -s flag was given * and we should not give default value to output_format. */ #define DIFF_FORMAT_NO_OUTPUT 0x0800 An unset output_format is given e.g. by repo_index_has_changes(). We could set it right there, but there may be other places, so simply let diff_flush() handle it for all of them consistently. Finally, capture the output of the external diff and only register a change by setting found_changes if the program wrote anything. Reported-by: German Lashevich Signed-off-by: René Scharfe --- diff.c | 33 ++++++++++++++++++++++++++++++--- t/t4020-diff-external.sh | 8 ++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/diff.c b/diff.c index ded9ac70df..cd3c8a3978 100644 --- a/diff.c +++ b/diff.c @@ -40,6 +40,7 @@ #include "setup.h" #include "strmap.h" #include "ws.h" +#include "write-or-die.h" #ifdef NO_FAST_WORKING_DIRECTORY #define FAST_WORKING_DIRECTORY 0 @@ -4404,8 +4405,33 @@ static void run_external_diff(const char *pgm, diff_free_filespec_data(one); diff_free_filespec_data(two); cmd.use_shell = 1; - if (run_command(&cmd)) - die(_("external diff died, stopping at %s"), name); + if (o->flags.diff_from_contents) { + int got_output = 0; + cmd.out = -1; + if (start_command(&cmd)) + die(_("external diff died, stopping at %s"), name); + for (;;) { + char buffer[8192]; + ssize_t len = xread(cmd.out, buffer, sizeof(buffer)); + if (!len) + break; + if (len < 0) + die(_("unable to read from external diff," + " stopping at %s"), name); + got_output = 1; + if (write_in_full(1, buffer, len) < 0) + die(_("unable to write output of external diff," + " stopping at %s"), name); + } + close(cmd.out); + if (finish_command(&cmd)) + die(_("external diff died, stopping at %s"), name); + if (got_output) + o->found_changes = 1; + } else { + if (run_command(&cmd)) + die(_("external diff died, stopping at %s"), name); + } remove_tempfile(); } @@ -4852,6 +4878,7 @@ void diff_setup_done(struct diff_options *options) */ if ((options->xdl_opts & XDF_WHITESPACE_FLAGS) || + options->flags.exit_with_status || options->ignore_regex_nr) options->flags.diff_from_contents = 1; else @@ -6742,7 +6769,7 @@ void diff_flush(struct diff_options *options) if (output_format & DIFF_FORMAT_CALLBACK) options->format_callback(q, options, options->format_callback_data); - if (output_format & DIFF_FORMAT_NO_OUTPUT && + if ((!output_format || output_format & DIFF_FORMAT_NO_OUTPUT) && options->flags.exit_with_status && options->flags.diff_from_contents) { /* diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index fdd865f7c3..26430ca66b 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -172,6 +172,14 @@ test_expect_success 'no diff with -diff' ' grep Binary out ' +test_expect_success 'diff.external and --exit-code with output' ' + test_expect_code 1 git -c diff.external=echo diff --exit-code +' + +test_expect_success 'diff.external and --exit-code without output' ' + git -c diff.external=true diff --exit-code +' + echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file test_expect_success 'force diff with "diff"' '