microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.16k stars 28.83k forks source link

Stage Selected Range Bug with Path Capitalisation #220541

Open hugs7 opened 3 months ago

hugs7 commented 3 months ago

Does this issue occur when all extensions are disabled?: Yes/No

VS Code Version:

OS Version: Edition Windows 11 Pro Version 23H2 Installed on ‎22/‎09/‎2022 OS build 22631.3810 Experience Windows Feature Experience Pack 1000.22700.1020.0

Steps to Reproduce:

Hey team. Think I've uncovered a bug with the stage selected / stage selected range feature in the latest VSCode Update. E.g. I've got a file /client/src/LetterWriter/toolbar/WriterToolbar.tsx where I want to stage just this change on line 88. See image below

image

When I click this + here, the following happens. For some reason VSCode thinks the capitalisation of the direct parent folder (actually toolbar with a lowercase "t") has changed to an uppercase. As seen below it duplicates the file in the working tree and the staged changes show the uppercase "T".

image

Is this a git bug somehow (Edit: I don't think so given my first comment)? On Github, the path is definitely lowercase and the same on my local disk. See below:

image image

I've tried clearing git cache but this issue is persistent and I've encountered the same issue with other folders too :(. I haven't ever changed the capitalisation of this toolbar folder.

The change (line 88) does move from the working tree but only on the file with the incorrect path. Before a recent update this feature worked perfectly. Has something changed? I really like this feature and it would be good if it could be fixed.

A git status does also show the same as VSCode's src control tab so I'm wondering if the issue might be there instead.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   client/src/components/LetterWriter/Toolbar/WriterToolbar.tsx           <<<< (observe wrong path)
        renamed:    client/src/components/LetterWriter/getSelectedNode.tsx -> client/src/components/LetterWriter/utils/getSelectedNode.tsx

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   client/src/components/LetterWriter/LetterWriter.tsx
        modified:   client/src/components/LetterWriter/Toolbar/WriterToolbar.tsx            <<<<<
        modified:   client/src/components/LetterWriter/toolbar/WriterToolbar.tsx             <<<<< (observe duplicate file with different path)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        client/src/components/LetterWriter/plugins/AutoLinkPlugin.tsx
        client/src/components/LetterWriter/plugins/FloatingLinkEditorPlugin/
        client/src/components/LetterWriter/plugins/LinkPlugin.tsx
        client/src/components/LetterWriter/utils/canUseDOM.ts
        client/src/components/LetterWriter/utils/setFloatingElemPositionForLinkEditor.ts
        client/src/utils/url.ts
hugs7 commented 3 months ago

For what it's worth, doing this in the command line with git add -p then following the commands works without issue. Is VSCode using git add -p or doing something else?

D:\Redacted\Documents\Redacted\Redacted>git add -p   client/src/components/LetterWriter/toolbar/WriterToolbar.tsx
diff --git a/client/src/components/LetterWriter/toolbar/WriterToolbar.tsx b/client/src/components/LetterWriter/toolbar/WriterToolbar.tsx
index 4d71187..665840b 100644
--- a/client/src/components/LetterWriter/toolbar/WriterToolbar.tsx
+++ b/client/src/components/LetterWriter/toolbar/WriterToolbar.tsx
@@ -33,9 +33,10 @@ import {
     UNDO_COMMAND,
     REDO_COMMAND,
     LexicalEditor,
+    KEY_MODIFIER_COMMAND,
 } from "lexical";
 import { $setBlocksType } from "@lexical/selection";
-import { $isLinkNode } from "@lexical/link";
+import { $isLinkNode, TOGGLE_LINK_COMMAND } from "@lexical/link";
 import {
     $isListNode,
     INSERT_CHECK_LIST_COMMAND,
(1/6) Stage this hunk [y,n,q,a,d,j,J,g,/,s,e,?]? n
@@ -85,14 +86,17 @@ import IconButton from "../../Inputs/IconButton";
 import { RadioOption } from "../../Inputs/RadioInput";
 import { TbFlask, TbLetterA, TbLetterASmall, TbTextResize } from "react-icons/tb";
 import { GrDocument } from "react-icons/gr";
-import { getSelectedNode } from "../getSelectedNode";
+import { getSelectedNode } from "../utils/getSelectedNode";
 import { FaCircle, FaRegCircle, FaRegSquareFull, FaSquareFull } from "react-icons/fa6";
 import { TOOLBAR_ICON_SIZE } from "../../../../constants/sizing";
 import { INSERT_PAGE_BREAK } from "../plugins/PageBreakPlugin";
 import { PARSE_REFERENCES_COMMAND, TOGGLE_REFERENCES_COMMAND } from "../plugins/ReferencePlugin";
+import { Dispatch } from "../../../utils/record";
+import { sanitizeUrl } from "../../../utils/url";

 interface ToolbarProps {
     toolbarRef: React.RefObject<HTMLDivElement>;
+    setIsLinkEditMode: Dispatch<boolean>;
 }

 class InvalidTagError extends Error {
(2/6) Stage this hunk [y,n,q,a,d,K,j,J,g,/,s,e,?]? s
Split into 3 hunks.
@@ -85,8 +86,8 @@ import IconButton from "../../Inputs/IconButton";
 import { RadioOption } from "../../Inputs/RadioInput";
 import { TbFlask, TbLetterA, TbLetterASmall, TbTextResize } from "react-icons/tb";
 import { GrDocument } from "react-icons/gr";
-import { getSelectedNode } from "../getSelectedNode";
+import { getSelectedNode } from "../utils/getSelectedNode";
 import { FaCircle, FaRegCircle, FaRegSquareFull, FaSquareFull } from "react-icons/fa6";
 import { TOOLBAR_ICON_SIZE } from "../../../../constants/sizing";
 import { INSERT_PAGE_BREAK } from "../plugins/PageBreakPlugin";
 import { PARSE_REFERENCES_COMMAND, TOGGLE_REFERENCES_COMMAND } from "../plugins/ReferencePlugin";
(2/8) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -89,7 +90,9 @@
 import { FaCircle, FaRegCircle, FaRegSquareFull, FaSquareFull } from "react-icons/fa6";
 import { TOOLBAR_ICON_SIZE } from "../../../../constants/sizing";
 import { INSERT_PAGE_BREAK } from "../plugins/PageBreakPlugin";
 import { PARSE_REFERENCES_COMMAND, TOGGLE_REFERENCES_COMMAND } from "../plugins/ReferencePlugin";
+import { Dispatch } from "../../../utils/record";
+import { sanitizeUrl } from "../../../utils/url";

 interface ToolbarProps {
     toolbarRef: React.RefObject<HTMLDivElement>;
(3/8) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? d

D:\Redacted\Documents\Redacted\Redacted>git st
On branch 5-custom-email-templates
Your branch is up to date with 'origin/5-custom-email-templates'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   client/src/components/LetterWriter/toolbar/WriterToolbar.tsx
        renamed:    client/src/components/LetterWriter/getSelectedNode.tsx -> client/src/components/LetterWriter/utils/getSelectedNode.tsx

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   client/src/components/LetterWriter/LetterWriter.tsx
        modified:   client/src/components/LetterWriter/toolbar/WriterToolbar.tsx

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        client/src/components/LetterWriter/plugins/AutoLinkPlugin.tsx
        client/src/components/LetterWriter/plugins/FloatingLinkEditorPlugin/
        client/src/components/LetterWriter/plugins/LinkPlugin.tsx
        client/src/components/LetterWriter/utils/canUseDOM.ts
        client/src/components/LetterWriter/utils/setFloatingElemPositionForLinkEditor.ts
        client/src/utils/url.ts
lszomoru commented 2 months ago

@hugs7, could you try to reproduce this issue in a small, isolated repository? That would significantly help us debug this issue. Thanks!

hugs7 commented 2 months ago

Sure, let me see if I can replicate

hugs7 commented 2 months ago

Was struggling to replicate this, even in the same repo for a moment but I think I got it. I think it's something to do with Windows allowing folder names to differ only by capitalisation, where as this isn't the case on Linux/macOS.

This wasn't how I came across the issue in the first place but to replicate the steps are below. I went back in my git history to see if I ever changed the /toolbar folder's capitalisation in the app I'm working on but I never did. Must be even another way to replicate this issue but sorry I wasn't able to reproduce it.

  1. Make git repo
  2. For the purposes of recreating this issue, I made a simple Vite app with npm create vite@latest and followed the prompts but I'm sure this bug would occur regardless. (b741e89ca0e17baa083a8ca7c3d89ee80ff9d7b3)
  3. Make a file (I made a component called Foo.tsx at path /src/components/Foo.tsx)
  4. Commit this file within VSCode to git (24cf8662040785c09416671dd64e01aeeba56ffe)
  5. Either within File Explorer or VSCode's Explorer tab, change the components folder to components_old
  6. Commit this change to git. (1cb1809de2109ea59aee9979ed59679c9ad7c89c)
  7. Not sure if this step is required but make a change to Foo.tsx. This can be any change. Commit this change to git. (37852d2c38825bb26239eb8ff2d2837c720b570a)
  8. Rename components_old to Components with a capital C.
  9. Commit the subsequent rename of the folder. (461b08bcbe8ac8dddad0aba8ac88bafb7becde5d)
  10. Now for the bug, make a change to Foo.tsx, now within the /src/Components directory
  11. Go to VSCode's Source Control tab and click Stage Block on (at least) one change. (I commited the incorrect change VSCode staged here: ea0e11cb1506cf8624cb6dac82a2c57be42513e8)
  12. Observe in the Source Control panel, the same issue described in my OP

E.g.

image

If I then go to commit the next changes image

The change with the lowercase components will be an empty change (f0d6e73c7a4e6b493690e45451cdb2f9a9d97112), and VSCode won't commit the other file, even if it's staged, but the change with the uppercase Components will produce an error and doesn't let me commit.

image

Logs below

2024-07-16 22:45:49.435 [info] > git add -A -- . [32ms]
2024-07-16 22:45:49.474 [info] > git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file - [36ms]
2024-07-16 22:45:49.510 [info] > git config --get-all user.name [32ms]
2024-07-16 22:45:49.538 [info] > git config --get-all user.email [25ms]
2024-07-16 22:45:49.565 [info] > git config --get commit.template [24ms]
2024-07-16 22:45:49.569 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) --ignore-case refs/heads/main refs/remotes/main [25ms]
2024-07-16 22:45:49.603 [info] > git status -z -uall [31ms]
2024-07-16 22:45:49.637 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) --ignore-case refs/heads/main refs/remotes/main [32ms]
2024-07-16 22:45:49.673 [info] > git config --local branch.main.vscode-merge-base [34ms]
2024-07-16 22:45:49.673 [warning] git config failed: Failed to execute git
2024-07-16 22:45:49.707 [info] > git reflog main --grep-reflog=branch: Created from *. [31ms]
2024-07-16 22:45:49.735 [info] > git symbolic-ref --short refs/remotes/origin/HEAD [25ms]
2024-07-16 22:45:49.735 [info] fatal: ref refs/remotes/origin/HEAD is not a symbolic ref
2024-07-16 22:45:51.339 [info] > git config --get commit.template [30ms]
2024-07-16 22:45:51.342 [info] > git ls-tree -l HEAD -- D:\Hugo\Documents\vscode-stage-selected\src\Components\Foo.tsx [30ms]
2024-07-16 22:45:51.346 [info] > git ls-tree -l HEAD -- D:\Hugo\Documents\vscode-stage-selected\src\App.tsx [31ms]
2024-07-16 22:45:51.352 [info] > git ls-tree -l HEAD -- D:\Hugo\Documents\vscode-stage-selected\src\Components\Foo.tsx [35ms]
2024-07-16 22:45:51.355 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) --ignore-case refs/heads/main refs/remotes/main [35ms]
2024-07-16 22:45:51.387 [info] > git show --textconv HEAD:src/App.tsx [35ms]
2024-07-16 22:45:51.387 [info] > git show --textconv HEAD:src/Components/Foo.tsx [39ms]
2024-07-16 22:45:51.392 [info] > git show --textconv HEAD:src/Components/Foo.tsx [37ms]
2024-07-16 22:45:51.395 [info] > git status -z -uall [36ms]
2024-07-16 22:45:51.427 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) --ignore-case refs/heads/main refs/remotes/main [29ms]
2024-07-16 22:45:51.453 [info] > git config --local branch.main.vscode-merge-base [24ms]
2024-07-16 22:45:51.453 [warning] git config failed: Failed to execute git
2024-07-16 22:45:51.485 [info] > git reflog main --grep-reflog=branch: Created from *. [29ms]
2024-07-16 22:45:51.511 [info] > git symbolic-ref --short refs/remotes/origin/HEAD [24ms]
2024-07-16 22:45:51.511 [info] fatal: ref refs/remotes/origin/HEAD is not a symbolic ref

I've performed these steps above on a test git repo for you. Please see: https://github.com/hugs7/vscode-stage-selected

I've also tried to provide the commit hash next to the relevant steps listed above to match my repo. Interesting how the git log in VSCode does have --ignore-case in a few of the commands - maybe something to go off? Regardless given the steps above, it seems this issue could affect Linux/macOS too given we are renaming, then renaming back.

If you would like any further clarification please let me know - happy to help however I can.

hugs7 commented 2 months ago

If I try to make that final commit in cmd line, git will refuse to add the file! See shell output below.

D:\Hugo\Documents\vscode-stage-selected>git st
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/Components/Foo.tsx

no changes added to commit (use "git add" and/or "git commit -a")

D:\Hugo\Documents\vscode-stage-selected>git st
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/Components/Foo.tsx

no changes added to commit (use "git add" and/or "git commit -a")

D:\Hugo\Documents\vscode-stage-selected>
Matesaktesak commented 3 weeks ago

This is a huge issue for me and resulted in unintended deletion of many hours of work. Needs fixing ASAP.

lszomoru commented 2 weeks ago

This is a huge issue for me and resulted in unintended deletion of many hours of work. Needs fixing ASAP.

Could you please elaborate on how exactly this behaviour has results in data loss? Thanks!

vs-code-engineering[bot] commented 1 week ago

This issue has been closed automatically because it needs more information and has not had recent activity. See also our issue reporting guidelines.

Happy Coding!

hugs7 commented 1 week ago

Please can this be reopened @lszomoru . I provided a repo and detailed steps on how this issue can be replicated.