[PATCH] subrepos: support adding files in git subrepos

Mathias De Maré mathias.demare at gmail.com
Wed Feb 25 00:21:31 CST 2015


On Wed, Feb 25, 2015 at 2:46 AM, Matt Harbison <mharbison72 at gmail.com>
wrote:

> On Tue, 24 Feb 2015 02:49:49 -0500, Mathias De Maré <
> mathias.demare at gmail.com> wrote:
>
>  # HG changeset patch
>> # User Mathias De Maré <mathias.demare at gmail.com>
>> # Date 1424764162 -3600
>> #      Tue Feb 24 08:49:22 2015 +0100
>> # Node ID 391c33821c0399e40979ef2440289844f8e12756
>> # Parent  ff5caa8dfd993680d9602ca6ebb14da9de10d5f4
>> subrepos: support adding files in git subrepos
>>
>> This support includes correct matching, so includes,
>> excludes and patterns are all supported.
>>
>> diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
>> --- a/mercurial/subrepo.py
>> +++ b/mercurial/subrepo.py
>> @@ -1524,6 +1524,24 @@
>>              return False
>>     @annotatesubrepoerror
>> +    def add(self, ui, match, prefix, explicitonly, **opts):
>> +        rev = self._state[1]
>> +        if match.files():
>> +            files = match.files()
>> +        elif match.always():
>> +            self._gitcommand(["add", "--all"])
>> +            return []
>> +        else:
>> +            (modified, added, removed,
>> +             deleted, unknown, ignored, clean) = self.status(None)
>> +            files = unknown
>> +        if match:
>> +            files = [f for f in files if match(f)]
>>
>
> Will match ever be None, since .files() was called on it first?
>
Hm, I'll go over the code calling this, I'm unsure.

>
>  +        for f in files:
>> +            self._gitcommand(["add", f])
>> +        return []
>> +
>> +    @annotatesubrepoerror
>>      def remove(self):
>>          if self._gitmissing():
>>              return
>>
>
> Do we need this _gitmissing() check for add() too?  Don't forget to update
> mercurial/help/subrepos.txt.
>
I'll have a look as well :-) Note that 'remove' is not for removing git
files, it's for removing the entire subrepository. 'forget' is used for
removing files (but is not yet implemented for git).

>
> I was surprised that the matcher has all of the files in it, but your
> tests seem to prove it does.  Looking at the code, it looks like it goes
> cmdutil.add() -> wctx.walk(match) -> dirstate.walk(), which I guess picks
> up the (non-hg?) subrepo files.  But that dirstate walk is called in a way
> to ignore the files in the parent repo's .hgignore.  And since it doesn't
> know git's ignore file, will it end up adding files git wants to ignore if
> a pattern _other_ than an exact file is supplied, like a glob?  (IDK if git
> will add ignored files if explicitly named like hg.  Maybe it isn't an
> issue.)
>
'git help add' says:

>    -f, --force
>        Allow adding otherwise ignored files.
>
> So without using that option, it should apparently be ok (though I wonder
if it would give an error in that case, I'll test).

>
> The .gitignore issue you can probably solve by always calling
> git.status(), and only acting on the intersection of unknown and
> match.files(), unless a file is match.exact() (or match.always()).  I'm not
> sure what to suggest about bypassing .hgignore, other than to walk again
> with the correct parameter?  Maybe _always_ iterating over unknown from
> git.status() and calling the matcher on each entry?  That may fix both
> cases, but opens the door to silently ignoring the error for adding an
> already tracked file.  That may not be worth worrying about.
>
I'll look into this in a bit more detail. Explicitly using the git status()
seems like the best fix, but I'll add some additional tests, both with a
.hgignore and with a .gitignore.

Thanks for the feedback!

Greetings,
Mathias

>
> --Matt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150225/ad6d8d98/attachment.html>


More information about the Mercurial-devel mailing list