Git:如何修复pooched跟踪

时间:2016-04-05 18:04:04

标签: git

问题: 由于错误构思的跟踪尝试,我在本地和远程回购中存在令人困惑的分支条目。有人可以帮我弄清楚如何修复或撤消我所做的事情吗?

详细说明: 为了更好地了解远程仓库中的内容何时发生变化,我尝试为所有分支机构添加跟踪关系。然而,事后来看,我并没有真正理解我所读到的内容,而且我做了一些不好的参赛作品(我想要摆脱但不确定如何不让事情变得更糟)。

我的本​​地和远程repos中的每个分支都有重复(kinda / sorta)条目。例如

$git branch -lvv
dev                630d6fd [remotes/origin/dev]
master             a7a913c [remotes/origin/master]
origin/dev         a4df258 [master: behind 3]
origin/master      a4df258 [master: behind 3]

git branch -rvv
origin/dev                630d6fd
origin/master             a7a913c
origin/origin/dev         a4df258
origin/origin/master      a4df258

我不清楚如何删除/删除/取消设置“origin / origin”条目而不会弄乱更多内容。我正在阅读文档和论坛,但我没有得到它。

修改 ......所以,我的不确定性围绕着“我不知道我要删除的东西”。换句话说,

  • 我只是删除哈希?这听起来很安全。
  • 或者我可以通过git branch -D origin/origin/master删除部分项目吗?

2 个答案:

答案 0 :(得分:2)

这里的问题(好吧, 问题 s 之一:-))git正在尝试友好,乐于助人且方便,并且这个过程让混乱局面更令人困惑。

安全第一

首先,让我们注意除了git push之外,您所做的一切只会影响您自己的存储库。您的origin/whatever条目只是副本您上次执行origingit push时git在git fetch上看到的内容。 (请注意,git pull是为方便起见的另一项内容;它运行git fetch,这是实际更新"我,你的git,当我看到的内容的步骤最后查看了复制到存储库的远程"条目。)

这意味着,即使我们破坏了事物,我们也只会在git push之前将其分解。不一定伟大但至少我们有点安全。 : - )

参考

接下来,让我们折回窗帘,看看分支和远程跟踪分支名称​​实际的工作方式。运行此命令:

$ git for-each-ref

你应该看到类似这样的输出:

...
a7a913c................................. commit refs/heads/master
a4df258................................. commit refs/heads/origin/master
...
a4df258................................. commit refs/remotes/origin/origin/master

(我在...标记了未知,无趣,不关心等内容。)

查看右侧的完整引用名称:有些名称以refs/heads/开头,有些名称以refs/remotes/开头(您甚至可能有其他人使用refs/tags/refs/stash)。这些是所有您的参考资料。

refs/heads/开头的是您的分支,以refs/remotes/开头的是您的远程跟踪分支git branch命令默认显示第一个设置(或使用-l),并在与-r一起使用时显示第二个设置。

请注意,refs/heads/origin/master明确地是名为origin/master的常规(本地)分支,refs/remotes/origin/master明确地是远程origin的远程跟踪分支,名为{{ 1}}。但是,当git帮助(?)剥离masterrefs/heads/部分时,您将同时离开refs/remotes/。有时git意识到这里似乎存在问题,并且仅剥离origin/master,只留下refs/:不再含糊不清,但仍然令人困惑。

remotes/origin/master(或git branch -d)删除了什么

与显示分支一样,-D前端在删除分支时也会尝试提供帮助。在没有git branch的情况下使用时,它只会删除本地分支,即以-r开头的引用。使用 refs/heads/时,它只会删除远程跟踪分支,即以-r开头的引用。因此:

refs/remotes/

删除本地分支$ git branch -D origin/master 。 (使用refs/heads/origin/master它会删除远程跟踪分支:可能不是你想要的,但不是那么大,因为你可以通过从远程获取来恢复它。)并且:

-r

删除远程跟踪分支$ git branch -r -D origin/origin/master (除非git感到困惑,在这种情况下,您可能不得不使用refs/heads/origin/origin/master,或编辑git update-ref和/或删除{{1但是,我最后一次看到这种bug是在我认为的git 1.7中。

到目前为止一切都那么好 - 我们现在知道如何说哪个引用会受到影响 - 但要重复部分标题, .git/packed-refs实际删除的内容是什么?答案是立即消失两件事:完整的引用名称 - 例如.git/refs/remotes/origin/origin/master - 以及该引用的 reflog (如果存在)。 reflog是git存储引用中保留的先前值的地方。这些是允许您使用git branch -drefs/heads/origin/master来查看之前引用的引用的内容。

提交本身怎么样?

这些提交至少会持续一段时间。

所有存储库对象 - 提交,带注释的标签,"树" (关于哪些文件具有哪些名称及其执行位的信息)和" blob" (文件内容,减去文件名:名称在树中) - 存储在其SHA-1下的存储库中。也就是说,对象的内容的哈希值是从git存储库中检索对象本身的关键,最后它基本上只是一个添加了一些包装器的键/值数据库。 / p>

对象本身将永远存在,最终,陈旧的对象会膨胀存储库,因此git有一个垃圾收集器master@{1}),它可以找到过时的,未引用的对象和抛弃它们。在执行往往会增加大量垃圾并可能需要一些收集的操作之后,Git会根据需要自动运行垃圾收集器。 dev@{1.week.ago}命令不是这些命令之一,即使删除引用可能会将大量引用的对象转换为未引用的对象。

尽管如此,您最终会运行git gc(即使只是您手动运行git branch)。此时,真正未引用的对象将被抛弃。但请暂时查看原始git gc输出:

git gc

请注意,git branchdev 630d6fd [remotes/origin/dev] master a7a913c [remotes/origin/master] origin/dev a4df258 [master: behind 3] origin/master a4df258 [master: behind 3] 都直接引用相同的提交。也就是说,它们具有相同的关联散列值origin/dev(为方便起见,截断为7个字符)。取出任何一个仍然会使另一个提交引用的提交,这显然可以保护它。

如果我们两个都拿出来怎么办?这有点棘手,但答案仍然在这里的引用输出中。这两个(本地)分支正在跟踪本地分支origin/master。提交a4df258指向master,这是不同的;但我们也看到了master,它告诉我们如果我们从提交a7a913c开始并通过其父提交回来,经过三个步骤我们就会来behind 3。< / p>

换句话说,如果我们绘制一些提交图,然后用它们的ID标记提交,我们将看到:

a7a913c

最正确的提交,我标记为a4df258(希望这个填充的圆圈在您的字体中有效)以及... <- o <- * <- o <- o <- ● <-- master 直接指向的。我们不知道下一个是什么,也不知道之后的那个,但我画的mastera7a913c

这意味着提交*仍然通过a4df258引用,只是间接引用(三步返回)。所以它不会消​​失。

结论

您可以安全地删除意外分支。 a4df258命令正常工作,只要您指定master删除远程跟踪分支并避免让git branch -D删除常规分支({1}}当地)分支机构。 (您需要先确保已签出其他分支,例如-r-r,因为master不允许您删除已签出的分支机构。)

答案 1 :(得分:0)

  

我不清楚如何删除/删除/取消设置“origin / origin”条目
  ..我想摆脱但不确定如何不让事情变得更糟

selector: function(userId) {
    return {
        _id: {$in: Roles.getUsersInRole('pending')
                        .map(function(user){ return user._id} ) }
    }
},