From 15dbcee54fc9bda3619d2feb806ea418d46e1dde Mon Sep 17 00:00:00 2001 From: Hunter Schoonover Date: Sat, 10 May 2025 18:03:10 -0500 Subject: [PATCH] Fixed normalized paths bug that prevented copying class in IDE. Issue 8497. If both repo and project paths were symlinks or network drive paths, copying with refactoring caused exceptions to be thrown. Other actions may have resulted in the same. A normalized file path canNOT be passed into getIgnores because getIgnores creates and executes a StatusCommand. Executing the StatusCommand passes the repository and the source file. StatusCommand gets the repository path by calling repository.getWorkTree(), which returns a non-normalized path. If both the repository and the source file are referenced via a symlink or network drive, referencing file paths via normalizing and non-normaling causes file path mismatches. The normalized file path points to another location on the system, but repository.getWorkTree() will provide a non-normalized file path. Signed-off-by: Hunter Schoonover --- .../git/jgit/commands/MoveTreeCommand.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/MoveTreeCommand.java b/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/MoveTreeCommand.java index 28060fb839ee..a2f7801883ea 100644 --- a/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/MoveTreeCommand.java +++ b/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/MoveTreeCommand.java @@ -77,23 +77,29 @@ protected void run() throws GitException { } sourceFile = tryNormalizeSymlink(sourceFile); targetFile = tryNormalizeSymlink(targetFile); + Repository repository = getRepository(); + + File repoWorkTreeNormalized = tryNormalizeSymlink(repository.getWorkTree()); + try { DirCache cache = repository.lockDirCache(); try { - List ignoredTargets = getIgnores(targetFile); + + List ignoredTargets = getIgnores(this.source); + boolean retried = false; DirCacheBuilder builder = cache.builder(); TreeWalk treeWalk = new TreeWalk(repository); - PathFilter sourceFilter = PathFilter.create(Utils.getRelativePath(repository.getWorkTree(), sourceFile)); - PathFilter targetFilter = PathFilter.create(Utils.getRelativePath(repository.getWorkTree(), targetFile)); + PathFilter sourceFilter = PathFilter.create(Utils.getRelativePath(repoWorkTreeNormalized, sourceFile)); + PathFilter targetFilter = PathFilter.create(Utils.getRelativePath(repoWorkTreeNormalized, targetFile)); treeWalk.setFilter(PathFilterGroup.create(Arrays.asList(sourceFilter, targetFilter))); treeWalk.setRecursive(true); treeWalk.reset(); treeWalk.addTree(new DirCacheBuildIterator(builder)); while (treeWalk.next() && !monitor.isCanceled()) { String path = treeWalk.getPathString(); - File file = new File(repository.getWorkTree().getAbsolutePath() + File.separator + path); + File file = new File(repoWorkTreeNormalized.getAbsolutePath() + File.separator + path); DirCacheEntry e = treeWalk.getTree(0, DirCacheBuildIterator.class).getDirCacheEntry(); if (e != null) { if (targetFilter.include(treeWalk)) { @@ -118,8 +124,8 @@ protected void run() throws GitException { // reset whole iterator and start from the beginning sourceFile = sourceFile.getCanonicalFile(); targetFile = targetFile.getCanonicalFile(); - sourceFilter = PathFilter.create(Utils.getRelativePath(repository.getWorkTree(), sourceFile)); - targetFilter = PathFilter.create(Utils.getRelativePath(repository.getWorkTree(), targetFile)); + sourceFilter = PathFilter.create(Utils.getRelativePath(repoWorkTreeNormalized, sourceFile)); + targetFilter = PathFilter.create(Utils.getRelativePath(repoWorkTreeNormalized, targetFile)); treeWalk.setFilter(PathFilterGroup.create(Arrays.asList(sourceFilter, targetFilter))); treeWalk.reset(); builder = cache.builder(); @@ -185,7 +191,9 @@ private void rename () throws GitException { private String getRelativePath (File file, File ancestor, File target) { String relativePathToAncestor = Utils.getRelativePath(ancestor, file); - StringBuilder relativePathToSource = new StringBuilder(Utils.getRelativePath(getRepository().getWorkTree(), target)); + StringBuilder relativePathToSource = new StringBuilder( + Utils.getRelativePath(tryNormalizeSymlink(getRepository().getWorkTree()), target) + ); if (!relativePathToAncestor.isEmpty()) { if (relativePathToSource.length() > 0) { relativePathToSource.append("/"); //NOI18N