From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v2] unpack-trees: do not abort when overwriting an existing file with the same content
Date: Mon, 21 Jan 2013 18:40:33 +0700 [thread overview]
Message-ID: <1358768433-26096-1-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1358594648-26851-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Changes: do not lose worktree's executable permission.
t/t1011-read-tree-sparse-checkout.sh | 3 ++-
t/t2021-checkout-overwrite.sh | 18 ++++++++++++++++++
unpack-trees.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index 5c0053a..38f9899 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -238,7 +238,8 @@ test_expect_success 'print errors when failed to update worktree' '
echo sub >.git/info/sparse-checkout &&
git checkout -f init &&
mkdir sub &&
- touch sub/added sub/addedtoo &&
+ echo modified >sub/added &&
+ echo modified >sub/addedtoo &&
test_must_fail git checkout top 2>actual &&
cat >expected <<\EOF &&
error: The following untracked working tree files would be overwritten by checkout:
diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh
index 5da63e9..bb1696d 100755
--- a/t/t2021-checkout-overwrite.sh
+++ b/t/t2021-checkout-overwrite.sh
@@ -47,4 +47,22 @@ test_expect_success SYMLINKS 'checkout commit with dir must not remove untracked
test -h a/b
'
+test_expect_success 'do not abort on overwriting an existing file with the same content' '
+ echo abc >bar &&
+ git add bar &&
+ git commit -m "new file" &&
+ git reset HEAD^ &&
+ git checkout HEAD@{1}
+'
+
+test_expect_success POSIXPERM 'do abort on an existing file, same content but different permission' '
+ git checkout -f HEAD^ &&
+ echo abc >bar &&
+ git add bar &&
+ git commit -m "new file" &&
+ git reset HEAD^ &&
+ chmod a+x bar &&
+ test_must_fail git checkout HEAD@{1}
+'
+
test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index 0e1a196..ea204ae 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -9,6 +9,8 @@
#include "refs.h"
#include "attr.h"
+#define SAME_CONTENT_SIZE_LIMIT (1024 * 1024)
+
/*
* Error messages expected by scripts out of plumbing commands such as
* read-tree. Non-scripted Porcelain is not required to use these messages
@@ -1363,6 +1365,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
struct unpack_trees_options *o)
{
struct cache_entry *result;
+ unsigned long ce_size;
/*
* It may be that the 'lstat()' succeeded even though
@@ -1405,6 +1408,34 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
return 0;
}
+ /*
+ * If it has the same content that we are going to overwrite,
+ * there's no point in complaining. We still overwrite it in
+ * the end though.
+ */
+ if (ce &&
+ S_ISREG(st->st_mode) && S_ISREG(ce->ce_mode) &&
+ (!trust_executable_bit ||
+ (0100 & (ce->ce_mode ^ st->st_mode)) == 0) &&
+ st->st_size < SAME_CONTENT_SIZE_LIMIT &&
+ sha1_object_info(ce->sha1, &ce_size) == OBJ_BLOB &&
+ ce_size == st->st_size) {
+ void *buffer = NULL;
+ unsigned long size;
+ enum object_type type;
+ struct strbuf sb = STRBUF_INIT;
+ int matched =
+ strbuf_read_file(&sb, ce->name, ce_size) == ce_size &&
+ (buffer = read_sha1_file(ce->sha1, &type, &size)) != NULL &&
+ type == OBJ_BLOB &&
+ size == ce_size &&
+ !memcmp(buffer, sb.buf, size);
+ free(buffer);
+ strbuf_release(&sb);
+ if (matched)
+ return 0;
+ }
+
return o->gently ? -1 :
add_rejected_path(o, error_type, name);
}
--
1.8.0.rc2.23.g1fb49df
next prev parent reply other threads:[~2013-01-21 11:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-19 11:24 [PATCH] unpack-trees: do not abort when overwriting an existing file with the same content Nguyễn Thái Ngọc Duy
2013-01-20 18:35 ` Junio C Hamano
2013-01-21 1:35 ` Duy Nguyen
2013-01-21 11:40 ` Nguyễn Thái Ngọc Duy [this message]
2013-01-21 23:15 ` [PATCH v2] " Jeff King
2013-01-22 0:59 ` Duy Nguyen
2013-01-22 1:45 ` Junio C Hamano
2013-01-22 1:55 ` Duy Nguyen
2013-01-22 20:19 ` Jeff King
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1358768433-26096-1-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/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.
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 NNTP newsgroup(s).