Thread (1 message) 1 message, 1 author, 2016-06-15

Re: [PATCH v4] git-apply: apply submodule changes

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:29

Sven Verdoolaege [off-list ref] writes:
quoted hunk
@@ -2096,8 +2142,15 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
 				    lstat(old_name, &st))
 					return -1;
 			}
-			if (!cached)
+			if (!cached) {
 				changed = ce_match_stat(ce, &st, 1);
+				if (S_ISGITLINK(patch->old_mode)) {
+					changed &= TYPE_CHANGED;
+					if (!changed &&
+					    verify_gitlink_clean(patch->old_name))
+						changed |= TYPE_CHANGED;
+				}
+			}
In this codepath, we know the patch wants to either modify the
path at old_name or remove old_name.  If we are going to affect
the work tree, we have run lstat on it, and ran checkout_entry() 
if we did not have anything there and did lstat() again.

I think the check "S_ISGITLINK(patch->old_mode)" is wrong
(that's where my confusion while reading your patch came from).
It has to check ce's mode, not patch->old_mode, because we are
verifying if the index matches with the work tree in this
codepath.  If you fix it to S_ISGITLINK(ntohl(ce->ce_mode)),
I think I can see what you are trying to do.

When ce is not a gitlink, you keep the original behaviour, which
is assuring that you did not break things for people who do not
use gitlink.

I am still having trouble with the TYPE_CHANGED bits.  You
discard everything other than TYPE_CHANGED, and 

 - if ce_match_stat() returned TYPE_CHANGED, then that is given
   to later processing to cause us to fail "oops, path is not up
   to date";

 - if ce_match_stat() did not return TYPE_CHANGED, that means we
   found a directory at the path (ce_match_stat_basic() says
   so).  In such a case you call verify_gitlink_clean(), but it
   essentially says "make sure there is either an empty
   directory or some repository".  Maybe we do not even have to
   have this extra check?

When ce is a gitlink, ce_match_stat() says DATA_CHANGED if the
commit in the work tree of the subproject is different.  From
the earlier discussions, we do want to discard DATA_CHANGED for
this codepath.

So it looks almost Ok after spending a few days looking at this
code.  Finally.

However, if it takes _me_ three days to understand this hunk,
(admittably, the parameter to S_ISGITLINK() completely confused
me originally, and I also had other things to do, so it was not
"72 hours"), I do not think the code with your patch is
maintainable by anybody.  At least we would need to have a few
words of comment to describe what is going on there.

	if (!cached) {
        	changed = ce_match_stat(ce, &st, 1);
                if (S_ISGITLINK(ntohl(ce->ce_mode)))
                	/*
			 * ce_match_stat() reports the
			 * difference between the commit object
                         * name in the index and what is checked
			 * out in the work tree of subproject;
                         * because we do not recurse, we do not
			 * want to insist on them matching with
                         * each other.
                         */
                	changed &= ~DATA_CHANGED;
	}
        if (changed)
        	return error("%s: does not match index", old_name);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help