簡體   English   中英

如何使 git 存儲庫中的現有目錄成為 git 子模塊

[英]How to make an existing directory within a git repository a git submodule

我對 git-submodules 很困惑。

基本上我的問題是我無法讓 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上點擊這些目錄的文件夾鏈接時,它並沒有將我定向到存儲庫本身,而是我留在同一個存儲庫中。

    1. 也許我錯過了整點。 子模塊的主要特點是什么?
    2. 為什么 git 可以理解dotfiles 存儲庫中的子模塊,但不能理解我的其他存儲庫中的子模塊?
    3. 是不是因為我已經告訴 git 將~/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 和我自己在之前的答案中所建議的那樣從頭開始,不如添加運行以下命令:

  1. 在不從索引中刪除子模塊的情況下,將子模塊的 url 添加到.gitmodules.git/config
    git submodule add <url> <path>
  2. 移動至子模塊的$GIT_DIR目錄( .git常規庫)來.git/modules/<path>
    git submodule absorbgitdirs <path>

原始答案 - v2.12.0 之前

git submodule absorbgitdirs僅在v2.12.0-rc0 中引入(請參閱commit )。

解決方案很簡單。 它是從這里提取的。

  1. git rm submodule-dir
    這將刪除 git 在submodule-dir之后跟蹤的所有文件
  2. rm -rf submoduledir
    這將刪除可能留在submodule-dir所有其他文件,因為 git 忽略了它們。
  3. 現在,我們必須提交才能從索引中刪除文件:
    git commit
    提交后,我們清理了 git 遵循的文件,而submodul-dir沒有遵循的文件。 現在是時候做:
  4. git submodule add <remote-path-to-submodule>
    這將重新添加子模塊,但作為真正的子模塊。
  5. 此時最好檢查.gitmodules並查看子模塊是否已成功添加。 就我而言,我已經有一個.gitmodules文件,所以我不得不修改它。

這些解決方案似乎都不適合我,所以我想出了自己的解決方案:

  1. 確保一個新的 git repo 已經存在,它將保存新子模塊的內容,例如,我們將使用“ git@github.com:/newemptyrepo

  2. 導航到您正在模塊化的目錄:

cd myproject/submodule-dir
  1. 從父項的索引中刪除要成為的子模塊:
git rm -r --cached .
  1. 在未來的子模塊中初始化一個新的 git repo:
git init
  1. 為未來的子模塊設置原點並進行第一次提交:
git remote add origin git@github.com:/newemptyrepo
git add . && git commit && git push --set-upstream origin master
  1. 現在您必須導航到父存儲庫的頂級路徑:
cd .. && cd `git rev-parse --show-toplevel`
  1. 最后,像往常一樣添加子模塊:
git submodule add git@github.com:/newemptyrepo ./myproject/submodule-dir
  1. 現在提交並推送上述命令所做的更改,您就完成了!

基本上沒有比假裝重新開始更好的方法了

  1. 確保在任何地方都承諾一切
  2. 將您的子存儲庫移開
  3. 從子存儲庫的遠程git submodule add
  4. cd mysubmodule
  5. git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
  6. git merge FETCH_HEAD

要解釋為什么是這樣的話,在我看來比一個更深入的了解什么需要的子模塊,比一個可以從搜集git-submodule(1)手冊頁(或者甚至是從Git的書相關章節)。 我在這篇博文中找到了一些更深入的解釋,但由於那篇文章有點長,我冒昧地在這里總結一下。

在底層,一個 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; 這顯然不同於主存儲庫的一組遙控器。 另請注意, .gitmodulesgit submodule sync命令和其他在幕后調用它的命令部分復制到.git/config

雖然手動對.gitmodules + .git/config以及.git/modules + mysubmodule/.git進行必要的更改相當容易(實際上,后者甚至還有git submodule absorbgitdirs ),但是並不是真正只創建樹內提交對象的瓷器 因此,建議的解決方案是通過移動 + 重做上面提出的更改。

要按順序回答您的問題:

  1. 根據 GitHub 的子模塊的目的 在功能方面,它被設計為一個子存儲庫(幾乎可以像對待任何其他文件一樣對待),即由父存儲庫控制的版本,其中父存儲庫跟蹤子模塊(子存儲庫)的當前提交 ID,而不是比它的內容
  2. 這很可能是因為您已經將文件添加到存儲庫的索引中。 在這種情況下,解決方案是git rm --cached submodule-name/ 然后創建一個中間提交,然后將文件夾添加為存儲庫git add submodule-name (注意在子模塊的情況下 submodule-name后面沒有斜杠)。
  3. 是的:)

您提到的答案也可能更正您提交的歷史記錄:

  1. 優點

該文件夾將被視為所有提交歷史記錄中的子模塊,而不僅僅是所有未來提交。 如果您檢出到以前的版本,在那里它被視為文件夾,這可以避免任何復雜化。 這是一個復雜的問題,因為當您返回到分支的頂端時,您可能還必須進入您的子模塊並簽出到最新提交以恢復所有文件(這些文件可能會從您的工作目錄中刪除)。 這可以通過對最新提交進行某種遞歸檢出來避免。

  1. 缺點

如果提交歷史被修改,所有其他貢獻者也必須重新克隆項目,因為他們會遇到合並沖突或更糟的情況; 重新將問題提交回項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM