2010/7/25 Nguyen Thai Ngoc Duy <[email protected]>:
> 2010/7/25 Jonathan Nieder <[email protected]>:
>> Frédéric Brière wrote:
>>
>>> I stumbled on this problem yesterday, working in a sparse checkout of
>>> linux-next.
>>
>> First of all, thanks for reporting this and sorry to take so long
>> to get back to you.
>>
>>> # See how the non-conflicting file is still in the index?
>>> git status
>>>
>>> # And see how reset --hard does not touch it, but --mixed does?
>>> git reset --hard
>>> git status
>>> git reset --mixed
>>> git status
>>
>> It seems that "read-tree --reset -u" should be somehow taught
>> to imply the effect of "read-tree --reset" (without -u). Duy: does
>> that seem reasonable? Are there any subtleties I should expect to
>> run into?
>
> Still studying the code. But does this help?
>
> diff --git a/unpack-trees.c b/unpack-trees.c
> index 8cf0da3..32764c2 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -1439,7 +1439,7 @@ int oneway_merge(struct cache_entry **src,
> struct unpack_trees_options *o)
>
> if (old && same(old, a)) {
> int update = 0;
> - if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) {
> + if (o->reset && !ce_uptodate(old)) {
> struct stat st;
> if (lstat(old->name, &st) ||
> ie_match_stat(o->src_index, old, &st,
> CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE))
Obviously not. When --mixed is used, unpack_tree_options.update is 0
(worktree not touched), thus disabling sparse checkout. When --hard is
used, opts.update is 1, and sparse checkout prevents anything outside
sparse area.
That "anything" should be "anything that touches worktree".
Unfortunately, CE_REMOVE (in the following patch) also means "remove
an entry from _index_". So by clearing out CE_REMOVE, it stops
more-boring.c from being removed from index too.
I'll make a proper patch to git ML later.
diff --git a/cache.h b/cache.h
index c9fa3df..c97269b 100644
--- a/cache.h
+++ b/cache.h
@@ -181,6 +181,7 @@ struct cache_entry {
/* Only remove in work directory, not index */
#define CE_WT_REMOVE (0x400000)
+#define CE_WT_NOREMOVE (0x2000000)
#define CE_UNPACKED (0x1000000)
diff --git a/unpack-trees.c b/unpack-trees.c
index 8cf0da3..e9672da 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -84,7 +84,8 @@ static int check_updates(struct unpack_trees_options *o)
if (o->update && o->verbose_update) {
for (total = cnt = 0; cnt < index->cache_nr; cnt++) {
struct cache_entry *ce = index->cache[cnt];
- if (ce->ce_flags & (CE_UPDATE | CE_REMOVE |
CE_WT_REMOVE))
+ if ((ce->ce_flags & (CE_UPDATE | CE_WT_REMOVE)) ||
+ ((ce->ce_flags & CE_REMOVE) & !(ce->ce_flags &
CE_WT_NOREMOVE)))
total++;
}
@@ -105,7 +106,7 @@ static int check_updates(struct unpack_trees_options *o)
continue;
}
- if (ce->ce_flags & CE_REMOVE) {
+ if ((ce->ce_flags & CE_REMOVE) && !(ce->ce_flags &
CE_WT_NOREMOVE)) {
display_progress(progress, ++cnt);
if (o->update)
unlink_entry(ce);
@@ -803,8 +804,11 @@ int unpack_trees(unsigned len, struct tree_desc
*t, struct unpack_trees_options
* area as a result of ce_skip_worktree() shortcuts in
* verify_absent() and verify_uptodate(). Clear them.
*/
- if (ce_skip_worktree(ce))
- ce->ce_flags &= ~(CE_UPDATE | CE_REMOVE);
+ if (ce_skip_worktree(ce)) {
+ ce->ce_flags &= ~CE_UPDATE;
+ if (ce->ce_flags & CE_REMOVE)
+ ce->ce_flags |= CE_WT_NOREMOVE;
+ }
else
empty_worktree = 0;
--
Duy
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]