我的目录结构类似于以下内容:
~/workspace/
-- proj1/
-- proj2/
proj1和proj2是针对不同工作的git repos。今天我想添加另一个项目,所以我在GitHub上分叉,然后在本地克隆我的fork。一切顺利,但后来我想添加上游遥控器,以便我可以稍后同步我的分叉。 不假思索地跑了
git remote add upstream <upstream:url>
git fetch upstream
git merge upstream/master
来自〜/ workspaces目录的。
这将上游repo的内容添加到〜/ workspaces目录中。它没有触及proj文件夹,这很好。
我从工作区删除了所有意外添加的文件,并按照我最初的预期设置了所有内容,但现在如果我从〜/ workspaces运行git log
,我将获得上游回购的历史记录。
什么是阻止git思考的最好方法〜/ workspaces是一个回购?
提前致谢
答案 0 :(得分:1)
假设您执行git merge
时一切都很干净,您可以git reset --hard HEAD^
取消合并,git remote remove upstream
删除遥控器和所有upstream/*
远程分支。
(通过执行git fetch upstream
加上合并提交的提交仍将在您的存储库中,但除了占用磁盘空间外,它们应该是无害的。最终,如果没有引用,它们将被垃圾收集。)
请记住,虽然git merge
在工作目录中做了很多工作,但最终,就存储库而言,所做的只是创建一个新的提交,作为其第一个父级,你所在的分支的前一个尖端,以及其余的父母,你合并的分支的尖端: 1
before merge:
...--o--o--T <-- HEAD=your-branch
...--o--o--o <-- upstream/master
after merge:
...--o--o--T
\
M <-- HEAD=your-branch
/
...--o--o--o <-- upstream/master
其中T
是您之前的分支提示,M
是合并提交。名称HEAD^
表示“查找当前分支的提示” - 即提交M
- “并返回其第一个父级”:即提交T
,通过合并的定义。然后,git reset --hard <sha-or-other-identifier>
告诉git做两件事:
your-branch
的提示设置为指向提交T
。--hard
的{{1}}部分)。步骤1使提交图看起来像这样:
git reset
完成此操作后,合并提交...--o--o--T <-- HEAD=your-branch
\
M [abandoned]
/
...--o--o--o <-- upstream/master
仍保留在存储库中,但没有分支或其他标签指向它, 2 所以我喜欢称之为“废弃”。大约30天后,当reflog条目到期并且提交被垃圾收集时,它真的会消失。如果您之前删除了M
,则垃圾收集upstream/master
也会导致整个较低的提交链也被收集,并且您将获得所有磁盘空间。
1 当然,作为其“树”,合并提交在合并后具有工作目录内容。
2 我的意思是标签,reflog条目本身不是标签。它们充当临时参考;它们默认持续30到90天,到期时间由两个配置项控制。较短(30天)到期适用于reflog条目,这些条目指向不从相应参考点所指向的提示的提交。
上面的内容很复杂,但这意味着,例如,如果您在分支M
上进行了一些提交,那么这些提交会进入devel
reflog。假设您进行了四次提交,然后devel
来“撤消”最后一次提交。分支git reset --hard HEAD^
的提示现在指向您的第三次提交。第三个提交指向您的第二个,第二个提交指向您的第一个。这三个reflog条目现在被认为比第四个提交更有价值:如果从提交devel
名称开始,则不能向后移动到第四个提交。
因此,其中三个reflog条目将持续90天,或者配置中devel
中的任何值。第四个只会持续30天,或gc.reflogexpire
中的任何值。
我刚刚注意到较新版本的git(哪些?)通过gc.reflogexpireunreachable
和gc.pattern.reflogexpire
来增强它。这意味着,例如,您可以将gc.ref.reflogexpireunreachable
设置为保持“上升”状态,例如gc.refs/stash.reflogexpireunreachable
,大约超过默认的30天,而不会将其他日志条目保留更长时间。