[英]How to make an existing directory within a git repository a git submodule
基本上我的問題是我無法讓 git 理解~/main-project/submodule
是一個子模塊。
我對 git 子模塊有很好的經驗:
在我的dotfiles 存儲庫中,我在~/dotfiles-repo
創建了 .gitmodules 文件,並在那里添加了路徑和 url。 從那時起,如果我對子模塊中的文件進行更改並運行git status
,我會得到類似的內容: .vim/bundle/auto-complete (new commits) # in red
我在~/main-project
創建了.gitmodules
文件,但是:
~/main-project/submodule
進行更改,甚至推送更改,在~/main-project
運行git status
時,我不會得到類似<submodule> (new commits) # in red
的類似響應。 我只是得到了在這些目錄中所做的更改當我在github
上點擊這些目錄的文件夾鏈接時,它並沒有將我定向到存儲庫本身,而是我留在同一個存儲庫中。
~/main-project/submodule
的文件添加到索引中? 我已經閱讀了這個問題,這使我得到了這個答案但我不確定我是否需要git-subtree
。 我不想做那些可能會造成難以恢復的變化的事情。
編輯: 這個建議的重復解決方案也不起作用,我收到一個錯誤,
Updates were rejected because the remote contains work that you do not have locally
。 似乎@GabLeRoux實際上告訴我將<repo-A>
推送到<repo-B>
的網址。
git submodule absorbgitdirs
這是該命令的文檔狀態:
如果子模塊的git目錄在子模塊里面,
$GIT_DIR/modules
的git目錄移動到它的superprojects$GIT_DIR/modules
路徑,然后通過設置core.worktree
並添加一個.git文件指向連接git目錄和它的工作目錄到嵌入在 superprojects git 目錄中的 git 目錄。
因此,與其像@DomQ 和我自己在之前的答案中所建議的那樣從頭開始,不如添加運行以下命令:
.gitmodules
和.git/config
中git submodule add <url> <path>
$GIT_DIR
目錄( .git
常規庫)來.git/modules/<path>
與git submodule absorbgitdirs <path>
git submodule absorbgitdirs
僅在v2.12.0-rc0 中引入(請參閱commit )。
解決方案很簡單。 它是從這里提取的。
git rm submodule-dir
submodule-dir
之后跟蹤的所有文件rm -rf submoduledir
submodule-dir
所有其他文件,因為 git 忽略了它們。git commit
submodul-dir
沒有遵循的文件。 現在是時候做:git submodule add <remote-path-to-submodule>
.gitmodules
並查看子模塊是否已成功添加。 就我而言,我已經有一個.gitmodules
文件,所以我不得不修改它。這些解決方案似乎都不適合我,所以我想出了自己的解決方案:
確保一個新的 git repo 已經存在,它將保存新子模塊的內容,例如,我們將使用“ git@github.com:/newemptyrepo ”
導航到您正在模塊化的目錄:
cd myproject/submodule-dir
git rm -r --cached .
git init
git remote add origin git@github.com:/newemptyrepo
git add . && git commit && git push --set-upstream origin master
cd .. && cd `git rev-parse --show-toplevel`
git submodule add git@github.com:/newemptyrepo ./myproject/submodule-dir
基本上沒有比假裝重新開始更好的方法了:
git submodule add
cd mysubmodule
git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
git merge FETCH_HEAD
要解釋為什么是這樣的話,在我看來比一個更深入的了解什么都需要的子模塊,比一個可以從搜集git-submodule(1)
手冊頁(或者甚至是從Git的書相關章節)。 我在這篇博文中找到了一些更深入的解釋,但由於那篇文章有點長,我冒昧地在這里總結一下。
在底層,一個 git 子模塊由以下元素組成,
.git/modules
子目錄,用於托管子模塊的 Git 對象,.gitmodules
配置文件中的一個條目。 提交對象包含在父樹對象中(或更准確地說,由 SHA1 引用)。 這是不尋常的,因為事情通常會反過來發生,但這解釋了為什么在子模塊中執行提交后,您會看到一個目錄出現在主存儲庫的git status
中。 你也可以用git ls-tree
做一些實驗來更詳細地觀察這個提交對象。
.git/modules
中的子目錄代表子.git/modules
中的.git
子目錄; 事實上,子模塊中有一個.git
文件,它使用gitdir:
行指向前者。 這是自 Git 1.7.8 版以來的默認行為。 不知道為什么如果你只是繼續擁有一個單獨的.git
目錄,為什么一切都不會正常工作,除非在發行說明中指出,在具有子模塊的分支和另一個沒有子模塊的分支之間切換時可能會遇到問題。
.gitmodules
文件提供了git submodule update --remote
和朋友應該從中拉取的 URL; 這顯然不同於主存儲庫的一組遙控器。 另請注意, .gitmodules
被git submodule sync
命令和其他在幕后調用它的命令部分復制到.git/config
。
雖然手動對.gitmodules
+ .git/config
以及.git/modules
+ mysubmodule/.git
進行必要的更改相當容易(實際上,后者甚至還有git submodule absorbgitdirs
),但是並不是真正只創建樹內提交對象的瓷器。 因此,建議的解決方案是通過移動 + 重做上面提出的更改。
要按順序回答您的問題:
git rm --cached submodule-name/
。 然后創建一個中間提交,然后將文件夾添加為存儲庫: git add submodule-name
(注意在子模塊的情況下 submodule-name后面沒有斜杠)。您提到的答案也可能更正您提交的歷史記錄:
該文件夾將被視為所有提交歷史記錄中的子模塊,而不僅僅是所有未來提交。 如果您檢出到以前的版本,在那里它被視為文件夾,這可以避免任何復雜化。 這是一個復雜的問題,因為當您返回到分支的頂端時,您可能還必須進入您的子模塊並簽出到最新提交以恢復所有文件(這些文件可能會從您的工作目錄中刪除)。 這可以通過對最新提交進行某種遞歸檢出來避免。
如果提交歷史被修改,所有其他貢獻者也必須重新克隆項目,因為他們會遇到合並沖突或更糟的情況; 重新將問題提交回項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.