如何取消删除通过 git rm 删除的子模块文件夹
how to undelete a folder that was a submodule removed via git rm
我需要取消删除显示为子模块的文件夹的未提交 git rm。
这比您想象的要复杂。
在 GitHub 我的私人仓库中,我找到了一个子模块。这是出乎意料的。 GitHub 项目页面将子模块显示为带有箭头的文件夹,但不可点击。
在本地有一个子模块名称的文件夹,其中有一个 .git 文件夹。表示已经git init
本地
我在本地重命名了子模块文件夹中的 .git 文件夹,并重命名了父文件夹中的 运行
git rm -f folder
认为它会摆脱子模块,只给我留下真正的文件夹,然后我可以 git add
回到 repo
但它在本地删除了文件夹,现在 none 以下命令似乎能够恢复它。
请记住,被列为子模块的文件夹从未提交给 git 服务器。但是它所在的文件夹有。
尝试了以下所有方法
git reset HEAD folder
git add folder
git checkout -- folder
git reset HEAD folder/*
并将 git 更新为 2.33.1 以尝试
git restore folder
git restore folder/*
和
git status
当前显示
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: folder
.git/config 没有引用子模块
我在这个帖子中读到的内容没有任何帮助
In my private repo on GitHub I found a submodule. This was unexpected. The GitHub project page showed the submodule as a folder with an arrow on it, but was not clickable.
这表明该子模块...充其量是不完整的,最坏的情况是完全损坏。
Locally there was a folder of the submodule's name and in it a .git
folder. Indicating that it had been git init
locally.
可能——或者您或某人 运行 git clone
来创建它。无论哪种方式,.git
目录(文件夹)包含实际的 存储库 。
如果该特定存储库还有其他克隆,则这些其他克隆存在,并且具有它们所具有的最新状态。如果没有,则它们不存在。
Locally I renamed the .git
folder in the submodule folder and ran from the parent git rm -f folder
没关系,除了一条重要信息。您已重命名(或移动)此 .git
。 你把它放在哪里了?
让我们设置一个类似的情况。请注意 Git 在此处打印的长警告和 hint
序列:
$ cd ~/tmp
$ mkdir tt
$ cd tt
$ git init
Initialized empty Git repository in .../tt/.git
$ mkdir sub
$ cd sub
$ git init
Initialized empty Git repository in .../tt/sub/.git
$ echo for testing > README
$ git add README
$ git commit -m initial
[master (root-commit) 1fd3599] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ cd ..
$ git add sub
warning: adding embedded git repository: sub
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: git submodule add <url> sub
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: git rm --cached sub
hint:
hint: See "git help submodule" for more information.
所做的是用 gitlink.
准备我的下一次提交
gitlink 是子模块中最重要的一半。另一半,也是最重要的,是进入 .gitmodules
文件的内容:这就是告诉 超级项目 Git(在 tt/
) 如何克隆子模块 tt/sub
.
由于我半途而废地制作了这个子模块,所以我只有一半子模块:gitlink 一半。这就是 GitHub 上不可点击的文件夹图标所代表的含义:一个 gitlink,其中子模块克隆指令要么完全缺失,要么不存在于 GitHub 上。 (如果子模块存储库在其他一些 public 访问站点上,也许他们会显示更多或允许点击,但如果它是完全私有的或丢失,他们 不能 显示更多;具体情况可以查看超级工程中的.gitmodules
文件查看。)
现在让我第一次提交 在 我的超级项目中(在 tt/
中),以便我实际引用子模块。然后我会做你做的:将 .git
文件夹移动到某处,然后 运行 git rm -f sub
:
$ git commit -m "initial in superproject"
[master (root-commit) 20ab8f6] initial in superproject
1 file changed, 1 insertion(+)
create mode 160000 sub
$ mv sub/.git save-the-repo
$ git rm -f sub
rm 'sub'
$ ls
save-the-repo
我还没有提交,但是一旦提交,我就有了一个没有 gitlink 的新提交。没有半评估的子模块,也没有完全评估的子模块:什么都没有,因为我从来没有把任何其他东西放到存储库中。当然,旧的commit仍然存在,它仍然引用子模块:
git commit -m 'remove half-assed submodule'
[master b01e217] remove half-assed submodule
1 file changed, 1 deletion(-)
delete mode 160000 sub
请注意 mode 160000
,顺便说一下:这就是 Git 用来将某物指定为 gitlink 的东西。我们可以在上一次提交中看到它,而在当前提交中它已经消失了:
$ git ls-tree -r HEAD^
160000 commit 1fd3599ca076ba9f03c88661013810a9536921ea sub
$ git diff HEAD^ HEAD
diff --git a/sub b/sub
deleted file mode 160000
index 1fd3599..0000000
--- a/sub
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 1fd3599ca076ba9f03c88661013810a9536921ea
回到你的问题
... thinking it would get rid of the submodule and just leave me with the real folder which I can then git add back into the repo
我现在必须重复这个问题(已在评论中和此答案中提出):您将原始 .git
文件夹放在哪里?
我把我的放在 save-the-repo
。我们在上面的 ls
输出中看到了它。你现在的工作是找个地方放它并在那个地方称它为 .git
:
$ mkdir recover
$ mv save-the-repo recover/.git
$ cd recover
$ git status
On branch master
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: README
no changes added to commit (use "git add" and/or "git commit -a")
要将文件恢复到最新版本,我现在可以按照上面的建议,或者更简单地说,git restore .
:
$ git restore .
$ ls
README
$ git status
On branch master
nothing to commit, working tree clean
请注意,这提取了 在 master
上的最新提交。这里的 .git
存储库仍然存在,并且仍然包含我所做的所有提交。我当然只做了一次提交,所以这就是所有的提交。但是,如果我现在将一个 README 文件移动到 sub
,那是 only 版本,我将保存回原始存储库:
$ cd ..
$ ls
recover
$ mkdir sub
$ mv recover/README sub/README
$ git add sub/README
$ git commit -m "move the latest sub/* files into the main repo, losing earlier ones"
[master 2af80e1] move the latest sub/* files into the main repo, losing earlier ones
1 file changed, 1 insertion(+)
create mode 100644 sub/README
$ git log --oneline
2af80e1 (HEAD -> master) move the latest sub/* files into the main repo, losing earlier ones
b01e217 remove half-assed submodule
20ab8f6 initial in superproject
我现在有三个提交:第一个,我有半成品子模块,第二个,我删除了它,第三个,我创建了 sub/
并用文件填充了它(好吧,文件,单数)来自曾经是子模块的最新提交。超级项目的 current 版本不依赖于任何子模块,但是 older 在超级项目中提交 - 因为没有 .gitmodules
给出了在何处克隆子模块的说明,那些半途而废的子模块已损坏。
真正解决这个问题,不留任何错误痕迹,将涉及从头开始创建新的历史记录,其中要么在开始时正确添加子模块,要么一开始就从未创建为 gitlink。然后,对于每个超级项目 and/or 子模块提交,我将进行另一个新提交以更新新组合项目中的所有文件。但这只是一个演示。
我需要取消删除显示为子模块的文件夹的未提交 git rm。
这比您想象的要复杂。
在 GitHub 我的私人仓库中,我找到了一个子模块。这是出乎意料的。 GitHub 项目页面将子模块显示为带有箭头的文件夹,但不可点击。
在本地有一个子模块名称的文件夹,其中有一个 .git 文件夹。表示已经git init
本地
我在本地重命名了子模块文件夹中的 .git 文件夹,并重命名了父文件夹中的 运行
git rm -f folder
认为它会摆脱子模块,只给我留下真正的文件夹,然后我可以 git add
回到 repo
但它在本地删除了文件夹,现在 none 以下命令似乎能够恢复它。 请记住,被列为子模块的文件夹从未提交给 git 服务器。但是它所在的文件夹有。
尝试了以下所有方法
git reset HEAD folder
git add folder
git checkout -- folder
git reset HEAD folder/*
并将 git 更新为 2.33.1 以尝试
git restore folder
git restore folder/*
和
git status
当前显示
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: folder
.git/config 没有引用子模块
我在这个帖子中读到的内容没有任何帮助
In my private repo on GitHub I found a submodule. This was unexpected. The GitHub project page showed the submodule as a folder with an arrow on it, but was not clickable.
这表明该子模块...充其量是不完整的,最坏的情况是完全损坏。
Locally there was a folder of the submodule's name and in it a
.git
folder. Indicating that it had beengit init
locally.
可能——或者您或某人 运行 git clone
来创建它。无论哪种方式,.git
目录(文件夹)包含实际的 存储库 。
如果该特定存储库还有其他克隆,则这些其他克隆存在,并且具有它们所具有的最新状态。如果没有,则它们不存在。
Locally I renamed the
.git
folder in the submodule folder and ran from the parentgit rm -f folder
没关系,除了一条重要信息。您已重命名(或移动)此 .git
。 你把它放在哪里了?
让我们设置一个类似的情况。请注意 Git 在此处打印的长警告和 hint
序列:
$ cd ~/tmp
$ mkdir tt
$ cd tt
$ git init
Initialized empty Git repository in .../tt/.git
$ mkdir sub
$ cd sub
$ git init
Initialized empty Git repository in .../tt/sub/.git
$ echo for testing > README
$ git add README
$ git commit -m initial
[master (root-commit) 1fd3599] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ cd ..
$ git add sub
warning: adding embedded git repository: sub
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: git submodule add <url> sub
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: git rm --cached sub
hint:
hint: See "git help submodule" for more information.
所做的是用 gitlink.
准备我的下一次提交gitlink 是子模块中最重要的一半。另一半,也是最重要的,是进入 .gitmodules
文件的内容:这就是告诉 超级项目 Git(在 tt/
) 如何克隆子模块 tt/sub
.
由于我半途而废地制作了这个子模块,所以我只有一半子模块:gitlink 一半。这就是 GitHub 上不可点击的文件夹图标所代表的含义:一个 gitlink,其中子模块克隆指令要么完全缺失,要么不存在于 GitHub 上。 (如果子模块存储库在其他一些 public 访问站点上,也许他们会显示更多或允许点击,但如果它是完全私有的或丢失,他们 不能 显示更多;具体情况可以查看超级工程中的.gitmodules
文件查看。)
现在让我第一次提交 在 我的超级项目中(在 tt/
中),以便我实际引用子模块。然后我会做你做的:将 .git
文件夹移动到某处,然后 运行 git rm -f sub
:
$ git commit -m "initial in superproject"
[master (root-commit) 20ab8f6] initial in superproject
1 file changed, 1 insertion(+)
create mode 160000 sub
$ mv sub/.git save-the-repo
$ git rm -f sub
rm 'sub'
$ ls
save-the-repo
我还没有提交,但是一旦提交,我就有了一个没有 gitlink 的新提交。没有半评估的子模块,也没有完全评估的子模块:什么都没有,因为我从来没有把任何其他东西放到存储库中。当然,旧的commit仍然存在,它仍然引用子模块:
git commit -m 'remove half-assed submodule'
[master b01e217] remove half-assed submodule
1 file changed, 1 deletion(-)
delete mode 160000 sub
请注意 mode 160000
,顺便说一下:这就是 Git 用来将某物指定为 gitlink 的东西。我们可以在上一次提交中看到它,而在当前提交中它已经消失了:
$ git ls-tree -r HEAD^
160000 commit 1fd3599ca076ba9f03c88661013810a9536921ea sub
$ git diff HEAD^ HEAD
diff --git a/sub b/sub
deleted file mode 160000
index 1fd3599..0000000
--- a/sub
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 1fd3599ca076ba9f03c88661013810a9536921ea
回到你的问题
... thinking it would get rid of the submodule and just leave me with the real folder which I can then git add back into the repo
我现在必须重复这个问题(已在评论中和此答案中提出):您将原始 .git
文件夹放在哪里?
我把我的放在 save-the-repo
。我们在上面的 ls
输出中看到了它。你现在的工作是找个地方放它并在那个地方称它为 .git
:
$ mkdir recover
$ mv save-the-repo recover/.git
$ cd recover
$ git status
On branch master
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: README
no changes added to commit (use "git add" and/or "git commit -a")
要将文件恢复到最新版本,我现在可以按照上面的建议,或者更简单地说,git restore .
:
$ git restore .
$ ls
README
$ git status
On branch master
nothing to commit, working tree clean
请注意,这提取了 在 master
上的最新提交。这里的 .git
存储库仍然存在,并且仍然包含我所做的所有提交。我当然只做了一次提交,所以这就是所有的提交。但是,如果我现在将一个 README 文件移动到 sub
,那是 only 版本,我将保存回原始存储库:
$ cd ..
$ ls
recover
$ mkdir sub
$ mv recover/README sub/README
$ git add sub/README
$ git commit -m "move the latest sub/* files into the main repo, losing earlier ones"
[master 2af80e1] move the latest sub/* files into the main repo, losing earlier ones
1 file changed, 1 insertion(+)
create mode 100644 sub/README
$ git log --oneline
2af80e1 (HEAD -> master) move the latest sub/* files into the main repo, losing earlier ones
b01e217 remove half-assed submodule
20ab8f6 initial in superproject
我现在有三个提交:第一个,我有半成品子模块,第二个,我删除了它,第三个,我创建了 sub/
并用文件填充了它(好吧,文件,单数)来自曾经是子模块的最新提交。超级项目的 current 版本不依赖于任何子模块,但是 older 在超级项目中提交 - 因为没有 .gitmodules
给出了在何处克隆子模块的说明,那些半途而废的子模块已损坏。
真正解决这个问题,不留任何错误痕迹,将涉及从头开始创建新的历史记录,其中要么在开始时正确添加子模块,要么一开始就从未创建为 gitlink。然后,对于每个超级项目 and/or 子模块提交,我将进行另一个新提交以更新新组合项目中的所有文件。但这只是一个演示。