From patchwork Wed Sep 18 20:27:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonathan Tan X-Patchwork-Id: 11151223 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8C8176 for ; Wed, 18 Sep 2019 20:27:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9FF3D21920 for ; Wed, 18 Sep 2019 20:27:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HM3jSd+S" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731245AbfIRU1m (ORCPT ); Wed, 18 Sep 2019 16:27:42 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:55861 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730892AbfIRU1m (ORCPT ); Wed, 18 Sep 2019 16:27:42 -0400 Received: by mail-pf1-f201.google.com with SMTP id w126so585964pfd.22 for ; Wed, 18 Sep 2019 13:27:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=pjkR/nGYbrsW3q9roD475+fduZUc3sYM4QgLgtsbGoU=; b=HM3jSd+Snbg5G9GZIr7jxBFAWC4pW4/4S85yegDZ64mCDB+ZqqLd/CY5nzx8Q82WDT q61L47jBt9hDECmuvUgcZHwaipVXmFjukKBTQoOv8zoBYbLu9FlbT0D0rK+KGTavpKNN h5UlisxnjECB2aMgYTh5auXx62D7t15ZKjF27AIHLj43R+R+poYX6V4gbhXFZlhtaTwU Ax1HmpZjSRyhThjzMOAJZHHoFyRkHlfduP6Px+J8nU0cSgajVUvCcpkVTSj6/uUWT8FQ 9WqeFfjWkMkK8bLi53NAPsVcqOnDk4AG1V+dMWQhAlaH8mDscmQyyimpxlJNVpFiwd9K 4TLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=pjkR/nGYbrsW3q9roD475+fduZUc3sYM4QgLgtsbGoU=; b=NXxMf0CtE/kLNsZxlH6H0fmNgT5sLdLCl+S4nCPxdwvuRg2jD1Zg+I52ii6l6Gy3Zm IFeMmkOuTkIchLB1SNPq1l7QzRipdUuHH+t+bISCYG/ygQsh5AV1Gtm9efoNLtYS+vqY y7UZ6pZ+JcopvhP/X2RXrcRaikGdY9WUCyC9oW2cqZ7M4JfrG4R1L6wgHni7s8JH5Mi8 HF94scg4Qf2EIUgTKylLscr1OHM8NXfOw2Lp0KUkbj28di6c5Joa0PJrmISs5QGKqRvF STVZRFSfqx5yg+mg2khqLarLL2wXaRWjrZjXGABrvhwNAcjNnMRZx6OKvdcloIgMaAuF z7yA== X-Gm-Message-State: APjAAAUbFRVsIw9Q5MHa8sQ0y82c4tSa36Mi5PNT0Ej4E9z83nXP05OX J3VfZVtK6zmfaAv/GxKRG5lEohI6kCZljG5BoaUq05Pghg0OyF8UX6SiK0p4ojqnt4dueaeD/xX EmZqDwgQRX6Hi6geB2M0LPs4uPtbH4hWDBVYtYHb4ElDThLVR3lo6UQPGi+Y0N5XOFyjbdgq//v RS X-Google-Smtp-Source: APXvYqxcM2PHp9J/QKix/Uxq4d6ZqZiHd+c7vRsrp0m/eXNmm6So5Z3VfXi+t7mvIOLptLHTxEQtyc5hqFTyjrDyRhwH X-Received: by 2002:a63:1521:: with SMTP id v33mr5772601pgl.9.1568838461107; Wed, 18 Sep 2019 13:27:41 -0700 (PDT) Date: Wed, 18 Sep 2019 13:27:38 -0700 In-Reply-To: Message-Id: <20190918202738.57273-1-jonathantanmy@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.23.0.237.gc6a4ce50a0-goog Subject: [PATCH v2] merge-recursive: symlink's descendants not in way From: Jonathan Tan To: git@vger.kernel.org Cc: Jonathan Tan , newren@gmail.com, gitster@pobox.com, szeder.dev@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org When the working tree has: - bar (directory) - bar/file (file) - foo (symlink to .) (note that lstat() for "foo/bar" would tell us that it is a directory) and the user merges a commit that deletes the foo symlink and instead contains: - bar (directory, as above) - bar/file (file, as above) - foo (directory) - foo/bar (file) the merge should happen without requiring user intervention. However, this does not happen. This is because dir_in_way(), when checking the working tree, thinks that "foo/bar" is a directory. But a symlink should be treated much the same as a file: since dir_in_way() is only checking to see if there is a directory in the way, we don't want symlinks in leading paths to sometimes cause dir_in_way() to return true. Teach dir_in_way() to also check for symlinks in leading paths before reporting whether a directory is in the way. Helped-by: Elijah Newren Signed-off-by: Jonathan Tan --- Changes from v1: - Used has_symlink_leading_path(). This drastically shortens the diff. - Updated commit message following suggestions from Junio, Szeder Gábor, and Elijah Newren. - Updated test to add prereq and verification that the working tree contains what we want. --- merge-recursive.c | 3 ++- t/t3030-merge-recursive.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/merge-recursive.c b/merge-recursive.c index 6b812d67e3..22a12cfeba 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -764,7 +764,8 @@ static int dir_in_way(struct index_state *istate, const char *path, strbuf_release(&dirpath); return check_working_copy && !lstat(path, &st) && S_ISDIR(st.st_mode) && - !(empty_ok && is_empty_dir(path)); + !(empty_ok && is_empty_dir(path)) && + !has_symlink_leading_path(path, strlen(path)); } /* diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index ff641b348a..faa8892741 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -452,6 +452,34 @@ test_expect_success 'merge-recursive d/f conflict result' ' ' +test_expect_success SYMLINKS 'dir in working tree with symlink ancestor does not produce d/f conflict' ' + git init sym && + ( + cd sym && + ln -s . foo && + mkdir bar && + >bar/file && + git add foo bar/file && + git commit -m "foo symlink" && + + git checkout -b branch1 && + git commit --allow-empty -m "empty commit" && + + git checkout master && + git rm foo && + mkdir foo && + >foo/bar && + git add foo/bar && + git commit -m "replace foo symlink with real foo dir and foo/bar file" && + + git checkout branch1 && + + git cherry-pick master && + test_path_is_dir foo && + test_path_is_file foo/bar + ) +' + test_expect_success 'reset and 3-way merge' ' git reset --hard "$c2" &&