From 7c08a2a6370ea70f16addcbad9096b4510a6b467 Mon Sep 17 00:00:00 2001 From: Ping Yin Date: Fri, 2 May 2008 21:35:33 +0800 Subject: [PATCH 1/5] t4027: test diff for submodule with empty directory Signed-off-by: Ping Yin Signed-off-by: Junio C Hamano --- t/t4027-diff-submodule.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 1fd3fb74d7..ba6679c6e4 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -50,4 +50,11 @@ test_expect_success 'git diff-files --raw' ' test_cmp expect actual.files ' +test_expect_success 'git diff (empty submodule dir)' ' + : >empty && + rm -rf sub/* sub/.git && + git diff > actual.empty && + test_cmp empty actual.empty +' + test_done From 27bfd950c19c76dce28a8c8693f4ed8603875d26 Mon Sep 17 00:00:00 2001 From: Ping Yin Date: Fri, 2 May 2008 21:35:34 +0800 Subject: [PATCH 2/5] Add t7506 to test submodule related functions for git-status Signed-off-by: Ping Yin Signed-off-by: Junio C Hamano --- t/t4027-diff-submodule.sh | 2 +- t/t7506-status-submodule.sh | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 t/t7506-status-submodule.sh diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index ba6679c6e4..61caad0f5d 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -50,7 +50,7 @@ test_expect_success 'git diff-files --raw' ' test_cmp expect actual.files ' -test_expect_success 'git diff (empty submodule dir)' ' +test_expect_failure 'git diff (empty submodule dir)' ' : >empty && rm -rf sub/* sub/.git && git diff > actual.empty && diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh new file mode 100755 index 0000000000..8987c9eb70 --- /dev/null +++ b/t/t7506-status-submodule.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +test_description='git-status for submodule' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_create_repo sub + cd sub && + : >bar && + git add bar && + git commit -m " Add bar" && + cd .. && + git add sub && + git commit -m "Add submodule sub" +' + +test_expect_success 'status clean' ' + git status | + grep "nothing to commit" +' +test_expect_success 'status -a clean' ' + git status -a | + grep "nothing to commit" +' +test_expect_success 'rm submodule contents' ' + rm -rf sub/* sub/.git +' +test_expect_success 'status clean (empty submodule dir)' ' + git status | + grep "nothing to commit" +' +test_expect_failure 'status -a clean (empty submodule dir)' ' + git status -a | + grep "nothing to commit" +' + +test_done From 1392a377219adfee7cc7532e3c60e51d79ab40b1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 May 2008 17:04:42 -0700 Subject: [PATCH 3/5] diff: a submodule not checked out is not modified 948dd34 (diff-index: careful when inspecting work tree items, 2008-03-30) made the work tree check careful not to be fooled by a new directory that exists at a place the index expects a blob. For such a change to be a typechange from blob to submodule, the new directory has to be a repository. However, if the index expects a submodule there, we should not insist the work tree entity to be a repository --- a simple directory that is not a full fledged repository (even an empty directory would do) should be considered an unmodified subproject, because that is how a superproject with a submodule is checked out sparsely by default. This makes the function check_work_tree_entity() even more careful not to report a submodule that is not checked out as removed. It fixes the recently added test in t4027. Signed-off-by: Junio C Hamano --- diff-lib.c | 25 ++++++++++++++++++++++--- t/t4027-diff-submodule.sh | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/diff-lib.c b/diff-lib.c index cfd629da48..e0ebcdcf54 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -337,9 +337,15 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) } return run_diff_files(revs, options); } + /* - * See if work tree has an entity that can be staged. Return 0 if so, - * return 1 if not and return -1 if error. + * Has the work tree entity been removed? + * + * Return 1 if it was removed from the work tree, 0 if an entity to be + * compared with the cache entry ce still exists (the latter includes + * the case where a directory that is not a submodule repository + * exists for ce that is a submodule -- it is a submodule that is not + * checked out). Return negative for an error. */ static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) { @@ -352,7 +358,20 @@ static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, return 1; if (S_ISDIR(st->st_mode)) { unsigned char sub[20]; - if (resolve_gitlink_ref(ce->name, "HEAD", sub)) + + /* + * If ce is already a gitlink, we can have a plain + * directory (i.e. the submodule is not checked out), + * or a checked out submodule. Either case this is not + * a case where something was removed from the work tree, + * so we will return 0. + * + * Otherwise, if the directory is not a submodule + * repository, that means ce which was a blob turned into + * a directory --- the blob was removed! + */ + if (!S_ISGITLINK(ce->ce_mode) && + resolve_gitlink_ref(ce->name, "HEAD", sub)) return 1; } return 0; diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 61caad0f5d..ba6679c6e4 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -50,7 +50,7 @@ test_expect_success 'git diff-files --raw' ' test_cmp expect actual.files ' -test_expect_failure 'git diff (empty submodule dir)' ' +test_expect_success 'git diff (empty submodule dir)' ' : >empty && rm -rf sub/* sub/.git && git diff > actual.empty && From 451244d724f921eca9ffaf526d45c825f7c6f4eb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 May 2008 17:23:46 -0700 Subject: [PATCH 4/5] diff-lib.c: rename check_work_tree_entity() The function is about checking for removed work tree item, so name it accordingly to avoid future confusion. Signed-off-by: Junio C Hamano --- diff-lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/diff-lib.c b/diff-lib.c index e0ebcdcf54..4a3e25536c 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -347,7 +347,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) * exists for ce that is a submodule -- it is a submodule that is not * checked out). Return negative for an error. */ -static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) +static int check_removed(const struct cache_entry *ce, struct stat *st, char *symcache) { if (lstat(ce->name, st) < 0) { if (errno != ENOENT && errno != ENOTDIR) @@ -421,7 +421,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); - changed = check_work_tree_entity(ce, &st, symcache); + changed = check_removed(ce, &st, symcache); if (!changed) dpath->mode = ce_mode_from_stat(ce, st.st_mode); else { @@ -485,7 +485,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (ce_uptodate(ce)) continue; - changed = check_work_tree_entity(ce, &st, symcache); + changed = check_removed(ce, &st, symcache); if (changed) { if (changed < 0) { perror(ce->name); @@ -543,7 +543,7 @@ static int get_stat_data(struct cache_entry *ce, if (!cached) { int changed; struct stat st; - changed = check_work_tree_entity(ce, &st, cbdata->symcache); + changed = check_removed(ce, &st, cbdata->symcache); if (changed < 0) return -1; else if (changed) { From 050288d52dc5dc3f6c7716007c1069dd9f59feb7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 May 2008 17:24:28 -0700 Subject: [PATCH 5/5] is_racy_timestamp(): do not check timestamp for gitlinks Because we do not even check the timestamp to determie if a gitlink is up to date or not, triggering the racy-timestamp check for gitlinks does not make sense. This fixes the recently added test in t7506. Signed-off-by: Junio C Hamano --- read-cache.c | 3 ++- t/t7506-status-submodule.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/read-cache.c b/read-cache.c index a92b25b59b..9ee125597e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -257,7 +257,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) static int is_racy_timestamp(const struct index_state *istate, struct cache_entry *ce) { - return (istate->timestamp && + return (!S_ISGITLINK(ce->ce_mode) && + istate->timestamp && ((unsigned int)istate->timestamp) <= ce->ce_mtime); } diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index 8987c9eb70..a75130cdbb 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -30,7 +30,7 @@ test_expect_success 'status clean (empty submodule dir)' ' git status | grep "nothing to commit" ' -test_expect_failure 'status -a clean (empty submodule dir)' ' +test_expect_success 'status -a clean (empty submodule dir)' ' git status -a | grep "nothing to commit" '