Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 338989 - Repository mapping does not correctly handle non container relative git directories
Summary: Repository mapping does not correctly handle non container relative git direc...
Status: RESOLVED FIXED
Alias: None
Product: EGit
Classification: Technology
Component: Core (show other bugs)
Version: 0.11   Edit
Hardware: All All
: P3 critical (vote)
Target Milestone: 2.0-M1   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-04 22:54 EST by Bhaskar Maddala CLA
Modified: 2012-02-27 18:13 EST (History)
5 users (show)

See Also:


Attachments
Fix for issue (6.31 KB, text/plain)
2011-03-06 00:53 EST, Bhaskar Maddala CLA
no flags Details
remove the use of getCanonicalFile() (922 bytes, patch)
2011-03-11 18:05 EST, Brad Davis CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bhaskar Maddala CLA 2011-03-04 22:54:29 EST
When a git repository is not relative to the container *IContainer* the git path handling in org.eclipse.egit.core.project.RepositoryMapping results in an exception 

org.eclipse.jgit.errors.NoWorkTreeException: Bare Repository has neither a working tree, nor an index
	at org.eclipse.jgit.lib.Repository.getWorkTree(Repository.java:1089)
	at org.eclipse.egit.ui.internal.sharing.ExistingOrNewPage.fillTreeItemWithGitDirectory(ExistingOrNewPage.java:273)

when attempting team->share project->git

This is because the constructor for RepositoryMapping

public RepositoryMapping(final IContainer mappedContainer, final File gitDir) {
  ...
}

does not keep track of non relative git repositories (else condition), and when returning an IPath instance thru getGitDirAbsolutePath always prefixes the git directory with container.getLocation() resulting the exception above. This was also raised in the forum a few days back

http://www.eclipse.org/forums/index.php?t=tree&th=205024&S=b952d8f9a5aec90ab9c9ff40165e3199
Comment 1 Bhaskar Maddala CLA 2011-03-06 00:53:28 EST
Created attachment 190483 [details]
Fix for issue

Attached a diff file highlight the changes required to make it work consistently. The change basically causes RepositoryMapping to return an absolute git dir path, instead of having the source location monkey with path, making assumptions about the relative location of the repository to the eclipse workspace.

Tested to verify the existing create repository for project continues to work.
Comment 2 Manuel Doninger CLA 2011-03-06 11:01:56 EST
Can you upload your change to the Code Review system Gerrit as described in http://wiki.eclipse.org/EGit/Contributor_Guide#Contributing_Patches ?
Comment 3 Bhaskar Maddala CLA 2011-03-06 17:19:53 EST
Added review in Gerrit

http://egit.eclipse.org/r/2653

However it would be great if Gerrit were enabled or had http access. Most places do not have access to port 29418
Comment 4 Matthias Sohn CLA 2011-03-06 17:30:15 EST
(In reply to comment #3)
> Added review in Gerrit
> 
> http://egit.eclipse.org/r/2653
> 
> However it would be great if Gerrit were enabled or had http access. Most
> places do not have access to port 29418

you can reach Gerrit over http at http://egit.eclipse.org/egit.git, generate your http password here : http://egit.eclipse.org/r/#settings,http-password
Comment 5 Bhaskar Maddala CLA 2011-03-07 13:46:03 EST
I am not entirely certain why the code ever required to convert absolute git dir paths to relative git dir paths. Not enough background on whether with was done with the intent of representation on the GUI when selecting a repository of for some other functional reason.

For who ever reviews the code, some thing to keep in mind.

If only the absolute directories is necessary (which I think to be the case), I think there might be an opportunity to make RepositoryMapping simpler, but avoiding some of the code in the constructor.
Comment 6 Brad Davis CLA 2011-03-11 18:02:54 EST
I recently investigated this when I encountered an issue using EGit at Amazon.  The specific issue is that if your .git repository is actually a symlink to a path not directly relative to the container, then the attempting to share the project would fail.  I found the following:

 * RepositoryFinder.register(…) uses File.getCanonicalFile() 
 ** This is how the path ‘<project location>/.git’ gets turned into ‘<absolute path>/.git’.  Presumably they’re using getCanonicalFile() because they don’t to register multiple locations that actually resolve the same physical repository.  That’s fine, but getCanonicalFile() doesn’t do anything like that on a windows environment.  This is really more of a Windows JRE bug because you’d think it would resolve NTFS junctions the same way it does symlinks, but it doesn’t.
 ** If this was changed to use getAbsoluteFile() by default, this would fix the bug, but it would allow for the possibility that when sharing an item with git, you could see multiple entries for the repository that were actually the same on disc.  That’s really only a cosmetic issue though, so maybe not a big deal, and it’s the same behavior that it currently has on windows.

 * RepositoryMapping.RepositoryMapping(…) won’t always give a relative path to the repository
 ** This constructor takes the passed container and file location and tries to construct the smallest relative path from the container to the repo on the assumption that the repo is either in a sub-directory or an ancestor directory of the container.  Only if neither of those assumptions is true will you end up with an absolute path.
 ** If this was changed to try harder to create a relative path by finding the longest common path between the two input paths, this would fix the bug.  However, this wouldn’t really guarantee a relative path all the time since if the environment were Windows and the two paths were on different drives, there’s no possible relative path to create.  On the other hand the bug we’re seeing couldn’t manifest on Windows anyway because of the way the plugin searches for the repository and the difference in behavior of getCanonicalFile() on that system.  
 * ExistingOrNewPage.fillTreeItemWithGitDirectory(...) assumes a relative path to the repository
 ** My reading of RepositoryFinder.find(…) is that it will look for a .git directory in the project directory and then in any ancestor directory and then recursively into children of the project directory.  A naïve understanding of this combined with the behavior of the RepositoryMapping constructor would lead one to assume that you’d only get relative paths as input, but the use of getCanonicalFile() precludes that possibility.  Because its assuming a relative path it haphazardly combines an absolute path with the container path which ends up stripping off the leading ‘/’.  
 ** If this was changed to account for the possibility of an absolute path, this would fix the problem.
 * The whole UI needs overhaul
 ** The UI actually prevents you from specifying a repository location or creating a repository if it finds any candidate repository, but its criteria for candidate is pretty weak.  Since it will look in any ancestor directory it’s possible the UI will fail to allow you to specify a directory simply because you have a .git in your home directory
 ** Fixing this would require re-engineering the UI

While the existing patch would likely solve the problem, it has the undesirable effect of always forcing the *absolute canonical* path of the file into the UI, even if the repository is simply at './.git' relative to the container.  

I'm attaching the patch I proposed internally, which takes the first solution of removing the use of getCanonicalFile(), which will make the behavior of the plugin the same on both windows and linux.  I'd suggest that this minimal change would be an adequate solution until such time as the UI can be overhauled into something more polished.
Comment 7 Brad Davis CLA 2011-03-11 18:05:28 EST
Created attachment 191032 [details]
remove the use of getCanonicalFile()
Comment 8 Brad Davis CLA 2012-01-30 16:34:47 EST
It's been almost a year since I posted my patch.  Is there anything I can do to get it looked at?  Egit.eclipse.org appears to be non-functional.
Comment 9 Brad Davis CLA 2012-02-21 01:10:07 EST
Uploaded patch to gerrit:

https://git.eclipse.org/r/#/c/5126/
Comment 10 Matthias Sohn CLA 2012-02-27 18:13:34 EST
merged as 8cd38faca85662d839f72cf8c460d87020ee34a7

sorry, I missed that you posted this patch, we almost exclusively 
work in Gerrit, thanks for your contribution :-)