git浅克隆 - 如何删除“嫁接标签”,它是什么?

cod*_*der 6 git git-clone

所以我们创建了一个模板项目“template_proj.git”。

更新git 版本是:2.14.1 在 Windows 7 教授

我们有一个空的新项目,除了它们有一个带有 .gitignore 文件的提交。假设这些项目之一称为“projectA.git”。

所以我的方法是:

  1. 将 template_proj.git 克隆到名为“Project_A”的文件夹中。为此,我使用:clone template_prog.git --depth=1 --recursive
  2. 移除遥控器: git remote rm origin
  3. 添加新遥控器: git remote add origin projectA.git
  4. 强制合并项目: git pull origin master --allow-unrelated-histories

这很好用。注意:我不只是从模板克隆中删除我的 .git 文件夹的主要原因是它有子模块。

这给了我一个包含 3 个提交的 repo(这正是我想要的):

  • template_proj.git 的提示
  • projectA.git 的提示(且仅提交)
  • 包含两者新合并的提交。

然而,有一个与the tip of template_proj.git提交相关的特殊标签/分支“嫁接” 。我真的不想那样。

所以我的问题:

  • 这是执行此操作的有效方法(即有没有更好的方法)?
  • 我如何摆脱grafted标签?
  • grafted标签是什么?

我一直无法完全理解grafted真正是什么/意味着什么- 我确实搜索了它并找到了一些信息,但仍然不确定。作为 git 搜索中的关键字,它被更常见的项目推翻了(或者我的 google-fu 很弱):(

更新:这里的这个问题也不能完全回答: 浅克隆中的“嫁接”提交究竟是什么?- 因为它并没有真正说明为什么存在嫁接或如何处理它(如果有的话)。.git/info/grafts我的仓库中也没有:文件。

tor*_*rek 17

它不是一个标签,你不能在不使存储库变得非浅 ( e.g., git fetch --unshallow) 的情况下删除它。它是指示这是历史记录中断点的标记

但是,您可以通过加深历史记录来移动标记。由于标记存在于每次历史被切断的提交处,如果历史在您关心的点以下切断,您将看不到标记。例如,使用深度 2 会将标记放在您获得的提交下方。

背景说明

请注意,计算机科学家喜欢将他们的树倒置:而不是顶部的叶子,向地面的分支,然后将树干插入地面,计算机科学理论的人们从树干开始:

    |
Run Code Online (Sandbox Code Playgroud)

然后在它下面添加分支:

    |
   / \
Run Code Online (Sandbox Code Playgroud)

并将叶子放在底部。

出于 StackOverflow 的目的,我喜欢用左边的根/树干和右边的叶子来绘制我的树

        o--o
       /
o--o--o
       \
        o--o
Run Code Online (Sandbox Code Playgroud)

在这里,我们有一个带有两个分支的简单树。让我们标记分支:

        o--o   <-- master
       /
o--o--o
       \
        o--o   <-- develop
Run Code Online (Sandbox Code Playgroud)

恭喜,你现在了解 Git 的分支了! 好吧,也许还没有。:-) 它还有很多,包括提交形成一个而不是一个简单的树,但这就是我们此时所需要的:我们有我们需要说的浅克隆是什么。让我们绘制一个深度为 2 的浅层克隆,由同一个存储库制作:

        o--o   <-- master
       X

       X
        o--o   <-- develop
Run Code Online (Sandbox Code Playgroud)

在这里,我们仍然有两个相同的分支名称masterdevelop,它们仍然指向两个不同的提交。他们的每个提交都指向第二个(更早的)提交。这两个中的每一个都指向(共享的)第三次提交,但我们已经达到了我们的深度限制,所以每个都有一个标记——X划掉回到早期提交的链接。

这是您在运行时看到的这个标记git log或任何向您显示提交的内容。Git 需要知道它不应该尝试寻找更多的提交——它确实有的提交说“我之前的提交是……”但是之前的提交丢失了。如果没有标记,Git 会告诉您您的存储库已损坏。

如果我们将 设置--depth为 3,则标记更靠后:

        o--o   <-- master
       /
    X-o
       \
        o--o   <-- develop
Run Code Online (Sandbox Code Playgroud)

但是如果--depth设置为 1,则标记就在每次提示提交时,您将始终看到它。


cod*_*der 6

环顾四周后,我终于找到了我需要的东西——我是在遵循一长串问题 --> 答案 --> 问题链接 --> 答案 --> 第 12 条评论后找到的。无论如何,这里有一些选择:

  • git fetch --unshallow- 这会使您的克隆变得浅薄,并且基本上可以恢复完整的历史记录。不是我想要的,但我可以用它来撤消--depth=1克隆。
  • git filter-branch -f -- --all- 这似乎修剪掉了嫁接的位。注意:如果没有这个-f选项,它可以很好地工作,但它会让旧的提交踢来踢去,所以你最终得到 2 棵树(因为缺少更好的词),一次从嫁接点开始,另一棵是全新的。但这对一个随意的旁观者来说是混乱的 - 所以使用强制选项来修剪所有这些。

我的信息来源:how-do-i-remove-the-old-history-from-a-git-repository - 第 9 条评论突出显示了该-f选项(您必须展开评论)。

所以这完全与git嫁接有关。我没有得到 .git/info/grafts 文件,但我确实手动创建了一个echo <SOME-COMMIT-SHA> > .git/info/grafts。当我这样做时,我在grafted我选择的 commit-sha 上得到了第二个标签。所以我想你可以用它来选择一个点来切割历史git filter-branch...

真的需要阅读更多关于嫁接的信息,但它目前并不是我真正感兴趣的功能 - 否则在这种情况下要摆脱它:o

更新:

我不得不跑:

git filter-branch -- --all

然后

git filter-branch -f -- --all

作为一个两步过程......不太确定如何/为什么。第一个拆分它们,第二个删除无法访问的提交或其他什么?

来自 Toreks 评论的更新

现在我执行以下操作:

git clone <url> --recursive --depth=1
cd into folder
git remote rm origin
git remote add origin <new url>
git filter-branch -- --all
rm -rf .git/refs/original/*
Run Code Online (Sandbox Code Playgroud)

现在我可以正常操作以获取空的 proj/merge 然后推送我的更改:

git pull origin master
commit anything here if needed...
git push origin master
Run Code Online (Sandbox Code Playgroud)