From mboxrd@z Thu Jan 1 00:00:00 1970 From: IWAMOTO Toshihiro Subject: bug with git-diff --quiet Date: Thu, 23 Jan 2014 11:45:25 +0900 Message-ID: <20140123024525.B726248918@mail.valinux.co.jp> Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Thu Jan 23 03:45:31 2014 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1W6AIN-0003z1-Cb for gcvg-git-2@plane.gmane.org; Thu, 23 Jan 2014 03:45:31 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752609AbaAWCp1 (ORCPT ); Wed, 22 Jan 2014 21:45:27 -0500 Received: from mail.valinux.co.jp ([210.128.90.3]:42915 "EHLO mail.valinux.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751467AbaAWCp0 (ORCPT ); Wed, 22 Jan 2014 21:45:26 -0500 Received: from dhcp016.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with ESMTP id B726248918 for ; Thu, 23 Jan 2014 11:45:25 +0900 (JST) User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?ISO-2022-JP-2?B?R29qGyQoRCtXGyhC?=) APEL/10.8 Emacs/23.4 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: I found "git-diff --quiet" returns a zero exit status even if there's a change. The following sequence reproduces the bug: $ mkdir foo $ cd foo $ git init $ echo a > a.txt $ echo b >b.txt $ git add ?.txt $ git commit $ echo b >> b.txt $ touch a.txt $ git diff --quiet; echo $? Interestingly, if you issue "git-diff --quiet" again, it returns the expected exit status 1. The problem is in the optimization code in run_diff_files(). The function finds a.txt has different stat(2) data from .git/index and calls diff_change(), which sets DIFF_OPT_HAS_CHANGES. As the flag makes diff_can_quit_early() return 1, run_diff_files()'s loop finishes without calling diff_change() for b.txt. Then, diffcore_std() examines diff_queued_diff and clears DIFF_OPT_HAS_CHANGES, because a.txt is unchanged. This is how a change in b.txt is ignored by git-diff --quiet. Here's a obvious fix for this bug, but I think you can find a better fix. Thanks in advance. diff --git a/diff-lib.c b/diff-lib.c index 346cac6..0b8c58d 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -105,9 +105,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) int changed; unsigned dirty_submodule = 0; - if (diff_can_quit_early(&revs->diffopt)) - break; - if (!ce_path_match(ce, &revs->prune_data)) continue; -- IWAMOTO Toshihiro