* project.el: git submodules?
@ 2020-05-12 15:31 Gary Oberbrunner
2020-05-12 15:53 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Gary Oberbrunner @ 2020-05-12 15:31 UTC (permalink / raw)
To: emacs-devel
In project.el as of 3f2788d4acd53 (Dec 27 2019), there is this code:
+ (pcase backend
+ ('Git
+ ;; Don't stop at submodule boundary.
+ (or (vc-file-getprop dir 'project-git-root)
+ (vc-file-setprop dir 'project-git-root
+ (vc-find-root dir ".git/"))))
That is not working in my situation, by which I mean I call
(project-current) in a buffer in a git submodule and it returns '(Git
. "submodule-root") rather than the actual project root, despite the
comment there that says it shouldn't do that. Following through the
code I don't see how it's supposed to be detecting that it's in a
submodule. Looks like it just looks upwards for the dominating ".git/"
dir.
In a simple test it appears to work, but not in my real-world case.
Before I dig deeper into it, can anyone (Dmitry?) tell me where to
look for the submodule-detection logic?
--
Gary
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 15:31 project.el: git submodules? Gary Oberbrunner
@ 2020-05-12 15:53 ` Dmitry Gutov
2020-05-12 18:05 ` Michael Welsh Duggan
2020-05-12 18:33 ` Gary Oberbrunner
0 siblings, 2 replies; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 15:53 UTC (permalink / raw)
To: Gary Oberbrunner, emacs-devel
Hi Gary,
On 12.05.2020 18:31, Gary Oberbrunner wrote:
> In a simple test it appears to work, but not in my real-world case.
> Before I dig deeper into it, can anyone (Dmitry?) tell me where to
> look for the submodule-detection logic?
That's the logic (two last lines in your quote). In my testing,
submodules contain only a file names ".git", but not a ".git/" directory.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 15:53 ` Dmitry Gutov
@ 2020-05-12 18:05 ` Michael Welsh Duggan
2020-05-12 18:27 ` Dmitry Gutov
2020-05-12 20:58 ` John Yates
2020-05-12 18:33 ` Gary Oberbrunner
1 sibling, 2 replies; 34+ messages in thread
From: Michael Welsh Duggan @ 2020-05-12 18:05 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Gary Oberbrunner, emacs-devel
Dmitry Gutov <dgutov@yandex.ru> writes:
> Hi Gary,
>
> On 12.05.2020 18:31, Gary Oberbrunner wrote:
>> In a simple test it appears to work, but not in my real-world case.
>> Before I dig deeper into it, can anyone (Dmitry?) tell me where to
>> look for the submodule-detection logic?
>
> That's the logic (two last lines in your quote). In my testing,
> submodules contain only a file names ".git", but not a ".git/"
> directory.
It's not only submodules, though. Git worktrees also just use a .git
file.
--
Michael Welsh Duggan
(md5i@md5i.com)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:05 ` Michael Welsh Duggan
@ 2020-05-12 18:27 ` Dmitry Gutov
2020-05-12 19:36 ` Stefan Monnier
2020-05-12 20:51 ` Michael Welsh Duggan
2020-05-12 20:58 ` John Yates
1 sibling, 2 replies; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 18:27 UTC (permalink / raw)
To: Michael Welsh Duggan; +Cc: Gary Oberbrunner, emacs-devel
On 12.05.2020 21:05, Michael Welsh Duggan wrote:
> It's not only submodules, though. Git worktrees also just use a .git
> file.
I'm not an expert, and you can suggest better logic.
FWIW, the examples of git worktrees on my machine all include a ".git/"
directory. It's just that some of its contents are symbolic links.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:27 ` Dmitry Gutov
@ 2020-05-12 19:36 ` Stefan Monnier
2020-05-12 19:39 ` Dmitry Gutov
2020-05-12 20:45 ` Michael Welsh Duggan
2020-05-12 20:51 ` Michael Welsh Duggan
1 sibling, 2 replies; 34+ messages in thread
From: Stefan Monnier @ 2020-05-12 19:36 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
> FWIW, the examples of git worktrees on my machine all include a ".git/"
> directory. It's just that some of its contents are symbolic links.
Hmm... are you sure these are Git worktrees?
Maybe they're "poor man's git-worktrees" created by the old
`git-new-workdir` hack which has been made obsolete by the "new" `git
worktree` feature.
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 19:36 ` Stefan Monnier
@ 2020-05-12 19:39 ` Dmitry Gutov
2020-05-12 20:45 ` Michael Welsh Duggan
1 sibling, 0 replies; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 19:39 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 12.05.2020 22:36, Stefan Monnier wrote:
>> FWIW, the examples of git worktrees on my machine all include a ".git/"
>> directory. It's just that some of its contents are symbolic links.
> Hmm... are you sure these are Git worktrees?
> Maybe they're "poor man's git-worktrees" created by the old
> `git-new-workdir` hack which has been made obsolete by the "new" `git
> worktree` feature.
That's always possible. :-(
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 19:36 ` Stefan Monnier
2020-05-12 19:39 ` Dmitry Gutov
@ 2020-05-12 20:45 ` Michael Welsh Duggan
2020-05-12 20:53 ` Dmitry Gutov
2020-05-12 20:53 ` Michael Welsh Duggan
1 sibling, 2 replies; 34+ messages in thread
From: Michael Welsh Duggan @ 2020-05-12 20:45 UTC (permalink / raw)
To: Stefan Monnier
Cc: Michael Welsh Duggan, emacs-devel, Gary Oberbrunner, Dmitry Gutov
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> FWIW, the examples of git worktrees on my machine all include a ".git/"
>> directory. It's just that some of its contents are symbolic links.
>
> Hmm... are you sure these are Git worktrees?
> Maybe they're "poor man's git-worktrees" created by the old
> `git-new-workdir` hack which has been made obsolete by the "new" `git
> worktree` feature.
Pretty sure.
/tmp/$ git --version
/tmp$ mkdir git-test
/tmp$ cd git-test
/tmp/git-test$ mkdir repo
/tmp/git-test$ cd repo
/tmp/git-test/repo$ git init
Initialized empty Git repository in /tmp/git-test/repo/.git/
/tmp/git-test/repo$ echo "Test file" > repo
/tmp/git-test/repo$ git add repo
/tmp/git-test/repo$ git commit -m "Initial commit."
[master (root-commit) 544fba2] Initial commit.
1 file changed, 1 insertion(+)
create mode 100644 repo
/tmp/git-test/repo$ git worktree add ../worktree
Preparing worktree (new branch 'worktree')
HEAD is now at 544fba2 Initial commit.
/tmp/git-test/repo$ cd ../worktree/
/tmp/git-test/worktree$ ls -la .git
-rw-r--r-- 1 md5i md5i 51 May 12 16:42 .git
/tmp/git-test/worktree$ cat .git
gitdir: /tmp/git-test/repo/.git/worktrees/worktree
--
Michael Welsh Duggan
(md5i@md5i.com)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 20:45 ` Michael Welsh Duggan
@ 2020-05-12 20:53 ` Dmitry Gutov
2020-05-12 21:04 ` Stefan Monnier
2020-05-12 20:53 ` Michael Welsh Duggan
1 sibling, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 20:53 UTC (permalink / raw)
To: Michael Welsh Duggan, Stefan Monnier; +Cc: Gary Oberbrunner, emacs-devel
On 12.05.2020 23:45, Michael Welsh Duggan wrote:
> Stefan Monnier<monnier@iro.umontreal.ca> writes:
>
>>> FWIW, the examples of git worktrees on my machine all include a ".git/"
>>> directory. It's just that some of its contents are symbolic links.
>> Hmm... are you sure these are Git worktrees?
>> Maybe they're "poor man's git-worktrees" created by the old
>> `git-new-workdir` hack which has been made obsolete by the "new" `git
>> worktree` feature.
> Pretty sure.
>
> /tmp/$ git --version
> /tmp$ mkdir git-test
> /tmp$ cd git-test
> /tmp/git-test$ mkdir repo
> /tmp/git-test$ cd repo
> /tmp/git-test/repo$ git init
> Initialized empty Git repository in/tmp/git-test/repo/.git/
> /tmp/git-test/repo$ echo "Test file" > repo
> /tmp/git-test/repo$ git add repo
> /tmp/git-test/repo$ git commit -m "Initial commit."
> [master (root-commit) 544fba2] Initial commit.
> 1 file changed, 1 insertion(+)
> create mode 100644 repo
> /tmp/git-test/repo$ git worktree add ../worktree
> Preparing worktree (new branch 'worktree')
> HEAD is now at 544fba2 Initial commit.
> /tmp/git-test/repo$ cd ../worktree/
> /tmp/git-test/worktree$ ls -la .git
> -rw-r--r-- 1 md5i md5i 51 May 12 16:42 .git
> /tmp/git-test/worktree$ cat .git
> gitdir:/tmp/git-test/repo/.git/worktrees/worktree
Perhaps you could suggest an additional test to determine whether a
directory is a submodule, then?
The contents of '.git' there are fairly similar:
gitdir: ../../.git/modules/site-lisp/company
I guess we could look inside and see whether '.git/modules/' is a
substring. Detecting a project over Tramp will become a little bit
slower as a result, though.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 20:53 ` Dmitry Gutov
@ 2020-05-12 21:04 ` Stefan Monnier
2020-05-12 21:06 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Stefan Monnier @ 2020-05-12 21:04 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
> Perhaps you could suggest an additional test to determine whether
> a directory is a submodule, then?
Indeed, technically, a submodule is implemented in the same way as a worktree.
And in `elpa.git`, we use worktrees to implement our own notion
of submodule.
I get the impression that distinguishing the two amounts to guessing the
intent behind a particular directory layout, so there will never be
a 100% correct answer.
But I guess a first approximation is to check "is there another .git
somewhere further up the directory tree and if so, does it use
the same repository as the current .git does?".
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 21:04 ` Stefan Monnier
@ 2020-05-12 21:06 ` Dmitry Gutov
2020-05-12 21:09 ` Stefan Monnier
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 21:06 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 13.05.2020 00:04, Stefan Monnier wrote:
> But I guess a first approximation is to check "is there another .git
> somewhere further up the directory tree and if so, does it use
> the same repository as the current .git does?".
That seems to imply traversing up the directory tree until '/' in some
cases. Right?
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 21:06 ` Dmitry Gutov
@ 2020-05-12 21:09 ` Stefan Monnier
2020-05-14 0:32 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Stefan Monnier @ 2020-05-12 21:09 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
>> But I guess a first approximation is to check "is there another .git
>> somewhere further up the directory tree and if so, does it use
>> the same repository as the current .git does?".
> That seems to imply traversing up the directory tree until '/' in some
> cases. Right?
Yes (which is no worse than what we do when there's no .git at all ;-)
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 21:09 ` Stefan Monnier
@ 2020-05-14 0:32 ` Dmitry Gutov
2020-05-14 2:55 ` Stefan Monnier
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-14 0:32 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 13.05.2020 00:09, Stefan Monnier wrote:
>>> But I guess a first approximation is to check "is there another .git
>>> somewhere further up the directory tree and if so, does it use
>>> the same repository as the current .git does?".
>> That seems to imply traversing up the directory tree until '/' in some
>> cases. Right?
> Yes (which is no worse than what we do when there's no .git at all;-)
Hmm, good point.
I even have a patch, but here's another thought: wouldn't this
mistakenly punish people who keep their $HOME as a Git repository to
sync between machines?
Any other repositories they are working on are likely inside.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 0:32 ` Dmitry Gutov
@ 2020-05-14 2:55 ` Stefan Monnier
2020-05-14 15:04 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Stefan Monnier @ 2020-05-14 2:55 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
> I even have a patch, but here's another thought: wouldn't this mistakenly
> punish people who keep their $HOME as a Git repository to sync
> between machines?
Depends if the Git worktrees within their $HOME use the same repository
as the one used for $HOME.
But yes, if they do, then by all accounts, they would qualify as
"submodules" in my book (and the only way to tell if they should be
treated as such or not would be by asking the user).
But we could try and be more strict in our definition of what is
a "submodule" for the purpose of finding the project root. And it's
likely that in the end we should let the user control what happens,
because depending on the specific use of submodules, I can imagine cases
where the user would want to consider the project's root to be that of
the submodule rather than that of the containing Git tree.
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 2:55 ` Stefan Monnier
@ 2020-05-14 15:04 ` Dmitry Gutov
2020-05-14 17:57 ` Stefan Monnier
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-14 15:04 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 14.05.2020 05:55, Stefan Monnier wrote:
>> I even have a patch, but here's another thought: wouldn't this mistakenly
>> punish people who keep their $HOME as a Git repository to sync
>> between machines?
>
> Depends if the Git worktrees within their $HOME use the same repository
> as the one used for $HOME.
Not 'git worktrees' (to be clear), just random other work directories,
for work/hobby/etc projects.
> But we could try and be more strict in our definition of what is
> a "submodule" for the purpose of finding the project root. And it's
> likely that in the end we should let the user control what happens,
> because depending on the specific use of submodules, I can imagine cases
> where the user would want to consider the project's root to be that of
> the submodule rather than that of the containing Git tree.
Yes, a user option (inrended for dir-locals) is likely in order, but
users such as described above would have to set it in _all_ of their
work directories.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 15:04 ` Dmitry Gutov
@ 2020-05-14 17:57 ` Stefan Monnier
2020-05-14 19:29 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Stefan Monnier @ 2020-05-14 17:57 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
>>> I even have a patch, but here's another thought: wouldn't this mistakenly
>>> punish people who keep their $HOME as a Git repository to sync
>>> between machines?
>> Depends if the Git worktrees within their $HOME use the same repository
>> as the one used for $HOME.
> Not 'git worktrees' (to be clear), just random other work directories, for
> work/hobby/etc projects.
Yes, I make "work trees" in a generic sense not just in the `git worktree` sense.
> Yes, a user option (inrended for dir-locals) is likely in order, but users
> such as described above would have to set it in _all_ of their
> work directories.
Not if the repository they use for $HOME is different than the one they
use for ~/work, ~/my/hobby/, ...
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 17:57 ` Stefan Monnier
@ 2020-05-14 19:29 ` Dmitry Gutov
2020-05-14 20:01 ` Stefan Monnier
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-14 19:29 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 14.05.2020 20:57, Stefan Monnier wrote:
>>>> I even have a patch, but here's another thought: wouldn't this mistakenly
>>>> punish people who keep their $HOME as a Git repository to sync
>>>> between machines?
>>> Depends if the Git worktrees within their $HOME use the same repository
>>> as the one used for $HOME.
>> Not 'git worktrees' (to be clear), just random other work directories, for
>> work/hobby/etc projects.
>
> Yes, I make "work trees" in a generic sense not just in the `git worktree` sense.
>
>> Yes, a user option (inrended for dir-locals) is likely in order, but users
>> such as described above would have to set it in _all_ of their
>> work directories.
>
> Not if the repository they use for $HOME is different than the one they
> use for ~/work, ~/my/hobby/, ...
Then they'll only have to set it in ~/.dir-locals.el? Is that what you mean?
Here's the patch I made according to your description:
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index ac56537b97..bf737e821a 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -266,11 +266,18 @@ project-try-vc
(let* ((backend (ignore-errors (vc-responsible-backend dir)))
(root
(pcase backend
- ('Git
+ (`(or ,'Git ,'Hg)
;; Don't stop at submodule boundary.
- (or (vc-file-getprop dir 'project-git-root)
- (vc-file-setprop dir 'project-git-root
- (vc-find-root dir ".git/"))))
+ (or (vc-file-getprop dir 'project-vc-root)
+ (let* ((default-directory dir)
+ (root (vc-root-dir))
+ (parent (file-name-directory
+ (directory-file-name root))))
+ (vc-file-setprop dir 'project-vc-root
+ (or
+ (let ((default-directory parent))
+ (vc-root-dir))
+ root)))))
('nil nil)
(_ (ignore-errors (vc-call-backend backend 'root dir))))))
(and root (cons 'vc root))))
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 19:29 ` Dmitry Gutov
@ 2020-05-14 20:01 ` Stefan Monnier
2020-05-14 20:13 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Stefan Monnier @ 2020-05-14 20:01 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
> Here's the patch I made according to your description:
>
> diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
> index ac56537b97..bf737e821a 100644
> --- a/lisp/progmodes/project.el
> +++ b/lisp/progmodes/project.el
> @@ -266,11 +266,18 @@ project-try-vc
> (let* ((backend (ignore-errors (vc-responsible-backend dir)))
> (root
> (pcase backend
> - ('Git
> + (`(or ,'Git ,'Hg)
> ;; Don't stop at submodule boundary.
> - (or (vc-file-getprop dir 'project-git-root)
> - (vc-file-setprop dir 'project-git-root
> - (vc-find-root dir ".git/"))))
> + (or (vc-file-getprop dir 'project-vc-root)
> + (let* ((default-directory dir)
> + (root (vc-root-dir))
> + (parent (file-name-directory
> + (directory-file-name root))))
> + (vc-file-setprop dir 'project-vc-root
> + (or
> + (let ((default-directory parent))
> + (vc-root-dir))
> + root)))))
I'm not familiar enough with this code to understand what it does: which
part tests "is it a submodule"? Or alternatively, which part compares
the location of the two repositories?
Stefan
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 20:01 ` Stefan Monnier
@ 2020-05-14 20:13 ` Dmitry Gutov
2020-05-14 21:17 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-14 20:13 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 14.05.2020 23:01, Stefan Monnier wrote:
> + (or
> + (let ((default-directory parent))
> + (vc-root-dir))
> + root)))))
>
> I'm not familiar enough with this code to understand what it does: which
> part tests "is it a submodule"?
The removed part.
> Or alternatively, which part compares
> the location of the two repositories?
The part quoted above. If the parent directory of the root of the
current Git worktree belongs to a VC worktree (vc-root-dir returns
non-nil), use that worktree's root. Otherwise, use the root of the
current repo.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 20:13 ` Dmitry Gutov
@ 2020-05-14 21:17 ` Dmitry Gutov
2020-05-14 21:38 ` Michael Welsh Duggan
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-14 21:17 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
On 14.05.2020 23:13, Dmitry Gutov wrote:
> On 14.05.2020 23:01, Stefan Monnier wrote:
>> + (or
>> + (let ((default-directory parent))
>> + (vc-root-dir))
>> + root)))))
>>
>> I'm not familiar enough with this code to understand what it does: which
>> part tests "is it a submodule"?
>
> The removed part.
>
>> Or alternatively, which part compares
>> the location of the two repositories?
>
> The part quoted above. If the parent directory of the root of the
> current Git worktree belongs to a VC worktree (vc-root-dir returns
> non-nil), use that worktree's root. Otherwise, use the root of the
> current repo.
Ah. After re-reading your initial message, I think I understand it
better. But to compare, we'd need to read the contents of both .git
files/directories, right?
That, um, sounds more complex than the current solution. And more file
reads = worse performance over Tramp, so it's not just implementation
difficulty.
Regarding the particulars, I suppose if .git is a file, and it starts with
gitdir: ../../.git/
where the number of "../" is two or more, then the current dir is
probably a submodule.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 21:17 ` Dmitry Gutov
@ 2020-05-14 21:38 ` Michael Welsh Duggan
2020-05-15 1:21 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Michael Welsh Duggan @ 2020-05-14 21:38 UTC (permalink / raw)
To: Dmitry Gutov
Cc: Michael Welsh Duggan, Gary Oberbrunner, Stefan Monnier,
emacs-devel@gnu.org
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 14.05.2020 23:13, Dmitry Gutov wrote:
>> On 14.05.2020 23:01, Stefan Monnier wrote:
>>> + (or
>>> + (let ((default-directory parent))
>>> + (vc-root-dir))
>>> + root)))))
>>>
>>> I'm not familiar enough with this code to understand what it does: which
>>> part tests "is it a submodule"?
>>
>> The removed part.
>>
>>> Or alternatively, which part compares
>>> the location of the two repositories?
>>
>> The part quoted above. If the parent directory of the root of the
>> current Git worktree belongs to a VC worktree (vc-root-dir returns
>> non-nil), use that worktree's root. Otherwise, use the root of the
>> current repo.
>
> Ah. After re-reading your initial message, I think I understand it
> better. But to compare, we'd need to read the contents of both .git
> files/directories, right?
>
> That, um, sounds more complex than the current solution. And more file
> reads = worse performance over Tramp, so it's not just implementation
> difficulty.
>
> Regarding the particulars, I suppose if .git is a file, and it starts with
>
> gitdir: ../../.git/
>
> where the number of "../" is two or more, then the current dir is
> probably a submodule.
I think you can just look for ^gitdir:.*/\.git/modules/
After all, I believe submodules all end up having their metadata within
.git/modules.
--
Michael Welsh Duggan
(mwd@cert.org)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-14 21:38 ` Michael Welsh Duggan
@ 2020-05-15 1:21 ` Dmitry Gutov
2020-05-15 5:11 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-15 1:21 UTC (permalink / raw)
To: Michael Welsh Duggan
Cc: Michael Welsh Duggan, Gary Oberbrunner, Stefan Monnier,
emacs-devel@gnu.org
On 15.05.2020 00:38, Michael Welsh Duggan wrote:
> I think you can just look for ^gitdir:.*/\.git/modules/
> After all, I believe submodules all end up having their metadata within
> .git/modules.
OK.
Here's a patch you can try:
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index ac56537b97..bc79e7591b 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -268,9 +268,24 @@ project-try-vc
(pcase backend
('Git
;; Don't stop at submodule boundary.
- (or (vc-file-getprop dir 'project-git-root)
- (vc-file-setprop dir 'project-git-root
- (vc-find-root dir ".git/"))))
+ (or (vc-file-getprop dir 'project-vc-root)
+ (let* ((default-directory dir)
+ (root (vc-root-dir)))
+ (vc-file-setprop
+ dir 'project-vc-root
+ (cond
+ ((file-directory-p ".git")
+ root)
+ ((with-temp-buffer
+ (insert-file-contents ".git")
+ (goto-char (point-min))
+ (looking-at "gitdir:[./]+/\.git/modules/"))
+ (let* ((parent (file-name-directory
+ (directory-file-name root)))
+ (default-directory parent))
+ (vc-root-dir)))
+ (t root)))
+ )))
('nil nil)
(_ (ignore-errors (vc-call-backend backend 'root dir))))))
(and root (cons 'vc root))))
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-15 1:21 ` Dmitry Gutov
@ 2020-05-15 5:11 ` Dmitry Gutov
2020-05-15 7:40 ` Kévin Le Gouguec
0 siblings, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-15 5:11 UTC (permalink / raw)
To: Michael Welsh Duggan
Cc: Michael Welsh Duggan, Gary Oberbrunner, Stefan Monnier,
emacs-devel@gnu.org
On 15.05.2020 04:21, Dmitry Gutov wrote:
> OK.
>
> Here's a patch you can try:
>
> diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
> index ac56537b97..bc79e7591b 100644
> --- a/lisp/progmodes/project.el
I've just pushed an improved version of this patch to master.
And now that project.el is in ELPA, it should be updated soon as well
(look for version 0.1.1).
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-15 5:11 ` Dmitry Gutov
@ 2020-05-15 7:40 ` Kévin Le Gouguec
2020-05-15 19:17 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Kévin Le Gouguec @ 2020-05-15 7:40 UTC (permalink / raw)
To: Dmitry Gutov
Cc: Michael Welsh Duggan, Gary Oberbrunner, Stefan Monnier,
Michael Welsh Duggan, emacs-devel@gnu.org
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 15.05.2020 04:21, Dmitry Gutov wrote:
>> OK.
>> Here's a patch you can try:
>> diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
>> index ac56537b97..bc79e7591b 100644
>> --- a/lisp/progmodes/project.el
>
> I've just pushed an improved version of this patch to master.
>
> And now that project.el is in ELPA, it should be updated soon as well
> (look for version 0.1.1).
I've tried commit 779bc886:
✓ within "nested" projects (e.g. when $HOME is under version control,
and visiting the Emacs repo under ~/src/emacs), project-find-file uses
the innermost project (~/src/emacs) as root,
✓ at the root of a Git worktree (e.g. when ~/src/emacs-26.3 is a
worktree of ~/src/emacs, and visiting ~/src/emacs-26.3),
project-find-file uses the worktree (~/src/emacs-26.3) as root,
❌ in a subfolder of a Git worktree (e.g. in ~/src/emacs-26.3/src),
project-find-file signals:
> project-try-vc: Opening input file: No such file or directory, /home/$USER/src/emacs-26.3/src/.git
✓ at the root of a Git submodule (e.g. when ~/projects/foo/bar is a
submodule of ~/projects/foo, and visiting ~/projects/foo/bar),
project-find-file uses the parent module (~/projects/foo) as root,
❌ in a subfolder of a Git submodule (e.g. in
~/projects/foo/bar/baz), project-find-file signals:
> project-try-vc: Opening input file: No such file or directory, /home/$USER/projects/foo/bar/baz/.git
I hope I got that right. Thank you for working on this; I'd love for
project-find-file to finally work in worktrees :)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-15 7:40 ` Kévin Le Gouguec
@ 2020-05-15 19:17 ` Dmitry Gutov
0 siblings, 0 replies; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-15 19:17 UTC (permalink / raw)
To: Kévin Le Gouguec
Cc: Michael Welsh Duggan, Gary Oberbrunner, Stefan Monnier,
Michael Welsh Duggan, emacs-devel@gnu.org
Hi Kevin!
On 15.05.2020 10:40, Kévin Le Gouguec wrote:
> I've tried commit 779bc886:
>
> ✓ within "nested" projects (e.g. when $HOME is under version control,
> and visiting the Emacs repo under ~/src/emacs), project-find-file uses
> the innermost project (~/src/emacs) as root,
>
> ✓ at the root of a Git worktree (e.g. when ~/src/emacs-26.3 is a
> worktree of ~/src/emacs, and visiting ~/src/emacs-26.3),
> project-find-file uses the worktree (~/src/emacs-26.3) as root,
>
> ❌ in a subfolder of a Git worktree (e.g. in ~/src/emacs-26.3/src),
> project-find-file signals:
>
>> project-try-vc: Opening input file: No such file or directory, /home/$USER/src/emacs-26.3/src/.git
>
> ✓ at the root of a Git submodule (e.g. when ~/projects/foo/bar is a
> submodule of ~/projects/foo, and visiting ~/projects/foo/bar),
> project-find-file uses the parent module (~/projects/foo) as root,
>
> ❌ in a subfolder of a Git submodule (e.g. in
> ~/projects/foo/bar/baz), project-find-file signals:
>
>> project-try-vc: Opening input file: No such file or directory, /home/$USER/projects/foo/bar/baz/.git
Thank you for exhaustive testing. The failing cases should be fixed now.
> I hope I got that right. Thank you for working on this; I'd love for
> project-find-file to finally work in worktrees :)
I was not aware they didn't. :-( Apparently I've been using the old,
"fake" version of worktrees.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 20:45 ` Michael Welsh Duggan
2020-05-12 20:53 ` Dmitry Gutov
@ 2020-05-12 20:53 ` Michael Welsh Duggan
1 sibling, 0 replies; 34+ messages in thread
From: Michael Welsh Duggan @ 2020-05-12 20:53 UTC (permalink / raw)
To: Michael Welsh Duggan
Cc: Dmitry Gutov, Gary Oberbrunner, Stefan Monnier, emacs-devel
Forgot to include part of the output:
> /tmp/$ git --version
git version 2.26.2
> /tmp$ mkdir git-test
> /tmp$ cd git-test
> /tmp/git-test$ mkdir repo
> /tmp/git-test$ cd repo
> /tmp/git-test/repo$ git init
> Initialized empty Git repository in /tmp/git-test/repo/.git/
> /tmp/git-test/repo$ echo "Test file" > repo
> /tmp/git-test/repo$ git add repo
> /tmp/git-test/repo$ git commit -m "Initial commit."
> [master (root-commit) 544fba2] Initial commit.
> 1 file changed, 1 insertion(+)
> create mode 100644 repo
> /tmp/git-test/repo$ git worktree add ../worktree
> Preparing worktree (new branch 'worktree')
> HEAD is now at 544fba2 Initial commit.
> /tmp/git-test/repo$ cd ../worktree/
> /tmp/git-test/worktree$ ls -la .git
> -rw-r--r-- 1 md5i md5i 51 May 12 16:42 .git
> /tmp/git-test/worktree$ cat .git
> gitdir: /tmp/git-test/repo/.git/worktrees/worktree
--
Michael Welsh Duggan
(md5i@md5i.com)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:27 ` Dmitry Gutov
2020-05-12 19:36 ` Stefan Monnier
@ 2020-05-12 20:51 ` Michael Welsh Duggan
1 sibling, 0 replies; 34+ messages in thread
From: Michael Welsh Duggan @ 2020-05-12 20:51 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Michael Welsh Duggan, Gary Oberbrunner, emacs-devel
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 12.05.2020 21:05, Michael Welsh Duggan wrote:
>> It's not only submodules, though. Git worktrees also just use a .git
>> file.
>
> I'm not an expert, and you can suggest better logic.
git rev-parse --show-superproject-working-tree
This will return an empty string if CWD is not a submodule.
https://stackoverflow.com/questions/52047148/how-to-check-if-the-current-repository-is-the-top-level-git-repo/52913255
--
Michael Welsh Duggan
(md5i@md5i.com)
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:05 ` Michael Welsh Duggan
2020-05-12 18:27 ` Dmitry Gutov
@ 2020-05-12 20:58 ` John Yates
2020-05-13 7:19 ` Andreas Schwab
1 sibling, 1 reply; 34+ messages in thread
From: John Yates @ 2020-05-12 20:58 UTC (permalink / raw)
To: Michael Welsh Duggan; +Cc: Emacs developers, Gary Oberbrunner, Dmitry Gutov
On Tue, May 12, 2020 at 2:06 PM Michael Welsh Duggan <mwd@md5i.com> wrote:
>
> It's not only submodules, though. Git worktrees also just use a .git
> file.
Are you confusing git worktree with --separate-git-dir functionality?
/john
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 20:58 ` John Yates
@ 2020-05-13 7:19 ` Andreas Schwab
0 siblings, 0 replies; 34+ messages in thread
From: Andreas Schwab @ 2020-05-13 7:19 UTC (permalink / raw)
To: John Yates
Cc: Michael Welsh Duggan, Dmitry Gutov, Gary Oberbrunner,
Emacs developers
On Mai 12 2020, John Yates wrote:
> Are you confusing git worktree with --separate-git-dir functionality?
They both use a gitdir file. Also used by git submodule.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 15:53 ` Dmitry Gutov
2020-05-12 18:05 ` Michael Welsh Duggan
@ 2020-05-12 18:33 ` Gary Oberbrunner
2020-05-12 19:28 ` Dmitry Gutov
2020-05-12 19:44 ` Doug Davis
1 sibling, 2 replies; 34+ messages in thread
From: Gary Oberbrunner @ 2020-05-12 18:33 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: emacs-devel
In my case at least, you're right and my submodule is seriously
confused. It has a .git/ dir which disagrees with the ../.git/modules
one. That's what was causing my problem. I've been doing a lot of work
in that submodule (multiple upstream repos, merges, pushes, etc.) and
perhaps something I did made it create that.
Apparently the correct way to do this is "git rev-parse
--show-superproject-working-tree". See
https://stackoverflow.com/questions/7359204 for more info. (And in
fact that does work in my case even with my messed-up .git dir in the
submodule.)
--
Gary
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:33 ` Gary Oberbrunner
@ 2020-05-12 19:28 ` Dmitry Gutov
2020-05-12 19:34 ` Gary Oberbrunner
2020-05-12 19:44 ` Doug Davis
1 sibling, 1 reply; 34+ messages in thread
From: Dmitry Gutov @ 2020-05-12 19:28 UTC (permalink / raw)
To: Gary Oberbrunner; +Cc: emacs-devel
On 12.05.2020 21:33, Gary Oberbrunner wrote:
> In my case at least, you're right and my submodule is seriously
> confused. It has a .git/ dir which disagrees with the ../.git/modules
> one. That's what was causing my problem. I've been doing a lot of work
> in that submodule (multiple upstream repos, merges, pushes, etc.) and
> perhaps something I did made it create that.
How common do you think is such problem going to be? If it's rare, I'd
rather let you fix the local configuration and leave that part of the
code in Emacs simple. Unless this comes up again, of course.
> Apparently the correct way to do this is "git rev-parse
> --show-superproject-working-tree". See
> https://stackoverflow.com/questions/7359204 for more info. (And in
> fact that does work in my case even with my messed-up .git dir in the
> submodule.)
Thank you. Any idea which version of Git this was added in first? We'd
have to consider that for compatibility with older systems.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 19:28 ` Dmitry Gutov
@ 2020-05-12 19:34 ` Gary Oberbrunner
2020-05-12 19:41 ` Dmitry Gutov
0 siblings, 1 reply; 34+ messages in thread
From: Gary Oberbrunner @ 2020-05-12 19:34 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1379 bytes --]
How common would it be? Sorry, I don't know. Someone further down in that
SO article suggested your simple answer should work, but suggests that the
new command is preferred. Probably just my broken config.
According to that Stack Overflow article, that arg was added in git 2.13
(Q2 2017).
On Tue, May 12, 2020 at 3:28 PM Dmitry Gutov <dgutov@yandex.ru> wrote:
> On 12.05.2020 21:33, Gary Oberbrunner wrote:
> > In my case at least, you're right and my submodule is seriously
> > confused. It has a .git/ dir which disagrees with the ../.git/modules
> > one. That's what was causing my problem. I've been doing a lot of work
> > in that submodule (multiple upstream repos, merges, pushes, etc.) and
> > perhaps something I did made it create that.
>
> How common do you think is such problem going to be? If it's rare, I'd
> rather let you fix the local configuration and leave that part of the
> code in Emacs simple. Unless this comes up again, of course.
>
> > Apparently the correct way to do this is "git rev-parse
> > --show-superproject-working-tree". See
> > https://stackoverflow.com/questions/7359204 for more info. (And in
> > fact that does work in my case even with my messed-up .git dir in the
> > submodule.)
>
> Thank you. Any idea which version of Git this was added in first? We'd
> have to consider that for compatibility with older systems.
>
--
Gary
[-- Attachment #2: Type: text/html, Size: 2339 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 18:33 ` Gary Oberbrunner
2020-05-12 19:28 ` Dmitry Gutov
@ 2020-05-12 19:44 ` Doug Davis
2020-05-12 19:50 ` Gary Oberbrunner
1 sibling, 1 reply; 34+ messages in thread
From: Doug Davis @ 2020-05-12 19:44 UTC (permalink / raw)
To: Gary Oberbrunner; +Cc: emacs-devel, Dmitry Gutov
Gary Oberbrunner <garyo@oberbrunner.com> writes:
> In my case at least, you're right and my submodule is seriously
> confused. It has a .git/ dir which disagrees with the ../.git/modules
> one. That's what was causing my problem. I've been doing a lot of work
> in that submodule (multiple upstream repos, merges, pushes, etc.) and
> perhaps something I did made it create that.
>
> Apparently the correct way to do this is "git rev-parse
> --show-superproject-working-tree". See
> https://stackoverflow.com/questions/7359204 for more info. (And in
> fact that does work in my case even with my messed-up .git dir in the
> submodule.)
For potentially complex setups it might be worth defining a personal
project discovery scheme, write a function compatible with it, and add
that function to `project-find-functions'.
Personal example: the first time I spun up `eglot' in a project that was
composed of submodules I ran into the issue that project.el didn't find
the top level repository as the project where the language server should
be initialized (this was quite some time ago, I guess before submodule
support was added to project.el).
Since I was already a projectile user, the solution (which I found
thanks to a comment on an eglot GitHub issue) was to add a new function
to `project-find-functions' which just queried projectile for what it
determined to be the project root. This was possible at the time because
projectile will search up the directory tree for a .projectile file to
define a project root, and I was already using that discovery mechanism
for that particular repository.
I was lazy and used projectile as a middle-step, but I think it would be
pretty straight forward to write a function to search for .emacs-project
files or something.
Doug
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: project.el: git submodules?
2020-05-12 19:44 ` Doug Davis
@ 2020-05-12 19:50 ` Gary Oberbrunner
0 siblings, 0 replies; 34+ messages in thread
From: Gary Oberbrunner @ 2020-05-12 19:50 UTC (permalink / raw)
To: Doug Davis; +Cc: emacs-devel, Dmitry Gutov
eglot is exactly how I got to this :-)
In my case I can fix my submodule, but if there are other cases I
guess writing a `project-find-functions` function makes sense.
And, thanks to this exchange I just learned about git worktrees! Only
been using git for a dozen years, clearly still a newb.
-- Gary
On Tue, May 12, 2020 at 3:44 PM Doug Davis <ddavis@ddavis.io> wrote:
>
> Gary Oberbrunner <garyo@oberbrunner.com> writes:
>
> > In my case at least, you're right and my submodule is seriously
> > confused. It has a .git/ dir which disagrees with the ../.git/modules
> > one. That's what was causing my problem. I've been doing a lot of work
> > in that submodule (multiple upstream repos, merges, pushes, etc.) and
> > perhaps something I did made it create that.
> >
> > Apparently the correct way to do this is "git rev-parse
> > --show-superproject-working-tree". See
> > https://stackoverflow.com/questions/7359204 for more info. (And in
> > fact that does work in my case even with my messed-up .git dir in the
> > submodule.)
>
> For potentially complex setups it might be worth defining a personal
> project discovery scheme, write a function compatible with it, and add
> that function to `project-find-functions'.
>
> Personal example: the first time I spun up `eglot' in a project that was
> composed of submodules I ran into the issue that project.el didn't find
> the top level repository as the project where the language server should
> be initialized (this was quite some time ago, I guess before submodule
> support was added to project.el).
>
> Since I was already a projectile user, the solution (which I found
> thanks to a comment on an eglot GitHub issue) was to add a new function
> to `project-find-functions' which just queried projectile for what it
> determined to be the project root. This was possible at the time because
> projectile will search up the directory tree for a .projectile file to
> define a project root, and I was already using that discovery mechanism
> for that particular repository.
>
> I was lazy and used projectile as a middle-step, but I think it would be
> pretty straight forward to write a function to search for .emacs-project
> files or something.
>
> Doug
--
Gary
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2020-05-15 19:17 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-12 15:31 project.el: git submodules? Gary Oberbrunner
2020-05-12 15:53 ` Dmitry Gutov
2020-05-12 18:05 ` Michael Welsh Duggan
2020-05-12 18:27 ` Dmitry Gutov
2020-05-12 19:36 ` Stefan Monnier
2020-05-12 19:39 ` Dmitry Gutov
2020-05-12 20:45 ` Michael Welsh Duggan
2020-05-12 20:53 ` Dmitry Gutov
2020-05-12 21:04 ` Stefan Monnier
2020-05-12 21:06 ` Dmitry Gutov
2020-05-12 21:09 ` Stefan Monnier
2020-05-14 0:32 ` Dmitry Gutov
2020-05-14 2:55 ` Stefan Monnier
2020-05-14 15:04 ` Dmitry Gutov
2020-05-14 17:57 ` Stefan Monnier
2020-05-14 19:29 ` Dmitry Gutov
2020-05-14 20:01 ` Stefan Monnier
2020-05-14 20:13 ` Dmitry Gutov
2020-05-14 21:17 ` Dmitry Gutov
2020-05-14 21:38 ` Michael Welsh Duggan
2020-05-15 1:21 ` Dmitry Gutov
2020-05-15 5:11 ` Dmitry Gutov
2020-05-15 7:40 ` Kévin Le Gouguec
2020-05-15 19:17 ` Dmitry Gutov
2020-05-12 20:53 ` Michael Welsh Duggan
2020-05-12 20:51 ` Michael Welsh Duggan
2020-05-12 20:58 ` John Yates
2020-05-13 7:19 ` Andreas Schwab
2020-05-12 18:33 ` Gary Oberbrunner
2020-05-12 19:28 ` Dmitry Gutov
2020-05-12 19:34 ` Gary Oberbrunner
2020-05-12 19:41 ` Dmitry Gutov
2020-05-12 19:44 ` Doug Davis
2020-05-12 19:50 ` Gary Oberbrunner
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.