git切换分支的时候自动把文件删除了?

前提:之前这个AuthorizationController文件,是叫authorizationController,后面改了AuthorizationController。说下情况,但是我也不知道和这个有没有关系

问题:现在遇到一个非常奇怪的问题,凡是从develop分支切换到其他分支,不管是develop切换到master分支,还是切换到gjm分支、A分支、B分支,都会自动把AuthorizationController文件删除掉,一头雾水了,有没有大神能解答下
image.png

我尝试在gjm分支上使用git checkout app/Http/Controllers/Admin/AuthorizationController.php能恢复文件,但是等我切换到develop分支,再切换回来,又被删除了

补充了执行git checkout app/Http/Controllers/Admin/AuthorizationController.php命令的过程
image.png

阅读 1.3k
avatarAI BotBETA

问题:现在遇到一个非常奇怪的问题,凡是从develop分支切换到其他分支,不管是develop切换到master分支,还是切换到gjm分支、A分支、B分支,都会自动把AuthorizationController文件删除掉,一头雾水了,有没有大神能解答下

答案:这个问题可能是由于git的配置或者历史记录导致的。有几个可能的原因:

  1. 文件名大小写不敏感:如果你在Unix-like系统(如Linux或macOS)上工作,并且git配置为区分大小写(这是默认设置),那么文件名"AuthorizationController"和"authorizationController"会被视为两个不同的文件。在切换分支时,git可能会尝试跟踪这两个文件,但实际上只有一个存在,因此可能会删除或添加文件。
  2. 历史记录中的文件名更改:如果AuthorizationController在历史记录中曾经被重命名或删除,那么当你切换分支时,git可能会尝试应用这些更改。
  3. .gitignore文件:某些分支可能在.gitignore文件中包含了AuthorizationController,导致它在这些分支上被忽略。

解决方案:

  1. 检查.gitignore文件:查看所有相关分支的.gitignore文件,确保AuthorizationController没有被忽略。
  2. 检查历史记录:使用git log -- path/to/AuthorizationController查看该文件的提交历史,确保没有重命名或删除的历史记录。
  3. 更改文件名的大小写:尝试将所有分支中的文件名统一为"AuthorizationController"或"authorizationController",然后查看问题是否解决。
  4. 使用git mv进行重命名:如果确实需要更改文件名,使用git mv命令而不是直接更改文件系统上的文件名。这样可以确保所有分支都一致地跟踪这个重命名操作。
  5. 创建新的分支并尝试:创建一个新的分支,并尝试从develop切换到这个新分支,看看问题是否仍然存在。这可以帮助确定问题是否与特定的分支有关。
3 个回答
git add .

git commit -m '自定义message'

git checkout 分支

要做一次提交(commit)才行吧

猜测是因为你们之前 尝试把 authorizationController 改成 AuthorizationController,但是却发现 Git 里面居然没有变化,可能时因为给 git 配置了不区分文件名的大小写,所以这在 git 看了就好像没有什么变化一样,所以你们就有人直接把这个文件删除掉了,然后 commit,然后再加回来,或者你们的操作步骤就直接是删除、重新添加,而不是改名。

因为在 Windows 上,文件是不区分大小写的,但是 Git 里面却记录了两个仅大小写不同的文件名。

当再在 Windows 下操作时就会有问题了,因为 git 记录到的是你 删除了 authorizationController ,而 Windows 又不区分大小写,他就认为 authorizationController 就是 AuthorizationController,所以把 AuthorizationController 给删掉了。

使用以下步骤在 Linux 下创建一个可重现的包。

$ mkdir rename-files
$ cd rename-files
$ echo '123' > foo.txt
$ echo '123' > Foo.txt
$ git init
$ git status
$ git add .
$ git status
$ git config user.name foo
$ git config user.email foo@example.com
$ git commit -m "add 2 files"
$ git status
$ git checkout -b b01
$ git status
$ rm foo.txt
$ git status
$ git add .
$ git commit -m "rm foo.txt"
$ git bundle create all.bundle b01 master

然后把这个 all.bundle 拷贝到 Windows 上,执行

git clone all.bundle

就会看到一个提示。

Cloning into 'all'...
Receiving objects: 100% (5/5), done.
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:

  'Foo.txt'
  'foo.txt'

其实已经告诉了问题了,现在进去就只能看到 foo.txt ,而看不到 Foo.txt,在 Linux 下的 master ,这两个文件都是存在的。

当现在切换的 b01 分支时,就会出现问题了,这时候就发现 Foo.txt 被删除了(我们刚刚在 Linux 下的 b01 删除的)。

On branch b01
Your branch is up to date with 'origin/b01'.

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

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

如果此时使用 ls 命令,或者查看文件系统,就发现,刚刚的 foo.txt 不见了。


解决办法

git reset --hard HEAD
git checkout master
git mv foo.txt Foo.txt

ok。现在应该就可以了,你再切到 b01,就正常了。

我试了下,把 git 默认的忽略文件大小关闭后,确实能复现

git config --local core.ignorecase false

步骤:

  • 随便 clone 一个仓库
  • git config --local core.ignorecase false
  • 默认分支切换到一个新分支,随便修改一个文件的大小写后 commit
  • 再切换回默认分支,刚刚改过大小写的文件就被 delete 掉了

要解决得在修改文件名的时候用 git mv 来操作

git mv [fileName] [newFileName]
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏