If I have a commit in the past that points to one parent, but I want to change the parent that it points to, how would I go about doing that?
我恐怕找不到任何类似这种特殊场景的东西.
我有一个有很多历史的git存储库:500多个分支,500多个标签,可以追溯到2007年中期.它包含~19,500次提交.我们想在2010年1月1日之前删除所有历史记录,以使其更小更容易处理(我们将在存档库中保留历史记录的完整副本).
我知道我想要成为新存储库的根目录的提交.但是,我不能找出正确的git mojo来截断repo以从那个提交开始.我猜的是一些变种
git filter-branch
Run Code Online (Sandbox Code Playgroud)
涉及移植是必要的; 它也可能是必要的对待每一个我们要分别保持在200多个分支机构,然后修补回购重新走到一起(这是我不知道该怎么做).
有没有人做过这样的事情?如果重要的话,我有git 1.7.2.3.
我有一个Git存储库(A),它包含项目的开发直到某一点.然后我丢失了这个回购A打开的USB记忆棒.幸运的是,我有一个最新提交的备份,所以我可以稍后创建一个新的存储库(B),我导入最新项目的状态并继续开发.现在我恢复了丢失的USB记忆棒,所以我有两个Git存储库.
我想我不得不以某种方式将回购B重新命名为回购A,但我不知道如何做到这一点,也许使用fetch/pull和rebase?
我试图弄清楚Git中的"移植物"是什么.
例如,在这里的一个最新评论中,Tobu假设使用git-filter-branch和.git/info/grafts来连接两个存储库.
但我不明白为什么我需要这些移植物?似乎所有工作都没有最后两个命令.
什么是git commit generation number(黑客新闻链接)以及它们的意义是什么?
合并提交是至少有两个父级的提交.这些父母按特定顺序排列.
如果我当前在分支上master,并且我在分支中合并feature,我创建一个新的提交,其第一个父是提交master,第二个提交是提交feature.这个顺序通过跑步特别明显git log --first-parent.
* The merge commit
|\
| * The commit from `feature`
* | The commit from `master`
Run Code Online (Sandbox Code Playgroud)
说我现在认识到的顺序是南辕北辙:我打算到分支合并master到feature运行git checkout feature; git merge master.我想交换合并提交的父级的顺序,但我不想经历再次解决所有合并冲突的麻烦.我怎样才能做到这一点?
* The merge commit
|\
* | The commit from `feature`
| * The commit from `master`
Run Code Online (Sandbox Code Playgroud) 当您想要重新分支保持合并提交的分支时,您将传递该--preserve-merges标志.当你在git中合并不相关的历史时,你需要传递--allow-unrelated-histories旗帜.
如果您git rebase --preserve-merges在现有合并来自不相关的历史记录时正在执行,则会失败:
致命的:拒绝合并不相关的历史
如果您尝试git rebase --preserve-merges --allow-unrelated-histories失败,则:
错误:未知选项'allow-unrelated-histories'
有没有其他方法告诉rebase允许合并?
编辑:这是一个最小的复制:https://github.com/vossad01/rebase-unrelated-merge-reproduction
要重现结帐,请master执行:
git rebase --preserve-merges --onto origin/a-prime HEAD~2
Run Code Online (Sandbox Code Playgroud) 我使用我的本地分支feature为github仓库创建一个PR(我没有写入权限).后来我决定将其最后一次提交分成独立的PR,所以我将feature一个提交移回:
git checkout feature
git branch feature2
git reset --hard @~
git push -f
Run Code Online (Sandbox Code Playgroud)
第一个PR合并到上游,所以现在我要创建第二个PR:
git checkout master
git pull upstream master
git push origin
git checkout feature2
git rebase master
Run Code Online (Sandbox Code Playgroud)
不幸的是,事实证明git缺乏feature合并的信息master.因此,它没有意识到最近的共同基础feature2并且master非常接近:它只是feature.相反,它rebase一直回到共同基础,feature并且master好像它们从未合并过一样.结果,git rebase master变得不必要地混乱.
为什么Github失去通过上游PR feature合并的信息master?有没有办法提供Github这些信息?
最后,我不得不诉诸:
git checkout master
git checkout -b feature2_new
git cherry-pick feature2
Run Code Online (Sandbox Code Playgroud)
幸运的是,我只需要处理一次提交.甚至与单个提交,我认为这与真正的基础(如果混帐知道这件事),合并会优于cherry-pick …
我试图用git replace改写历史并替换树的一个不同的提交的树对象提交.我想把这个永久化.
该文档git replace似乎表明这是可能的.我修改了以下配方来替换如何将过去添加到git存储库中的提交?.
# setup a second branch with a different tree
# existing repo which already contains a few commits
git checkout master -b master2
echo "test file" > testfile.txt # a different tree
git add testfile.txt
git commit -m "test"
# save the SHA1 of the original tree for later reference
ORIG=$(git rev-parse master^{tree})
# replace the tree of master with the one from master2
git replace master^{tree} …Run Code Online (Sandbox Code Playgroud) 基本上,我只想(重新)设置A特定提交(commit)的父级(比方说提交B),这是某个分支的根提交x。在其中一个答案中建议我可以通过移植来做到这一点。稍后我会尝试一下,也许这是更好的方法。
然而,在阅读本文之前,我认为这应该可以通过rebase. 但是因为父提交A有点不同B,我只想保持整个分支的x原样,只需将父提交设置为其根提交B,我想我可能会使用该theirs策略 - 这似乎不存在。我早些时候偶然发现了这一点(并认为这是一个错误或在我的 Git 安装中),并且总是通过切换分支和使用策略来解决ours。然而,在这种情况下rebase,我被迫使用该theirs策略。
我的命令如下所示:
git rebase -s theirs --onto A --root x x--rebased
Run Code Online (Sandbox Code Playgroud) 我在一个有效地解决git怪的仓库中。
我想在git blame中忽略两个提交。
现在,每次我怪罪一行时,我都会看到[commit 2]的作者,而不是真正的逻辑作者。
我最终不得不做一个git log [file in question]替代方案,或者这个问题中列出的另一种解决方案。
每当我使用Intellij中的Annotate功能(基本上是git blame)时,这两个提交使我感到很难过。
有没有人在不重写历史的情况下解决过这个问题?
我遇到过这样的情况:git fsck调用返回多个损坏的链接。这是因为,对于此存储库,rm运行了一个命令并删除了多个写保护文件(发生了错误)。该存储库也没有最近的备份(再次犯了错误)。由于正在使用 Git,存储库并未完全丢失,但一些历史记录已被打乱。直到最近要重新同步到源时,这一点才被注意到,但由于历史记录被破坏,这一点失败了。
我想修复此历史记录(如果可能),以便它可以与上游源合并。我认识到我将无法取回完整的历史记录,因为某些文件刚刚消失,但我想在正常工作的情况下尽可能保留其中的内容。
我审阅了 Linus 的电子邮件“如何恢复损坏的 blob 对象”(麻省理工学院托管副本),并且还查看了:
与许多其他人一起,但我没有看到太多关于从提交到提交错误的断开链接的建议。请注意,我确实制作了此存储库的副本,因此我不会擦除任何内容。
的结果git fsck是
$ git fsck
broken link from commit <SHA1>
to commit <SHA2>
broken link from tree <SHA3>
to blob <SHA4>
...
dangling blob <SHA5>
missing commit <SHA2>
missing blob <SHA4>
...
Run Code Online (Sandbox Code Playgroud)
当我最终通过 git 历史记录时,git log我收到错误
error: Could not read <SHA2>
fatal: Failed to traverse parents of commit <SHA1>
Run Code Online (Sandbox Code Playgroud)
它靠近最后一个备份存在的位置,但不完全在那里,所以我没有重叠的覆盖范围。我想尝试反向遍历历史,认为我可以将日志从最旧的提交移动到最新的提交,但是
$ git log --reverse …Run Code Online (Sandbox Code Playgroud) 我的一位大学同事认为通过克隆存储库并将其内容复制到新的初始化存储库但没有.git原始存储库中的文件夹来分叉存储库是个好主意.之后,他只使用一次提交就提交了此副本,整个团队就开始根据此提交开发项目:
A <- B <- C <- D <- E (original repository)
\ clone / |_____|
\ / |
\ / Ofc. work on the original repository was continued after cloning...
\ /
M <- N <- O <-P (our "fork", commits from my team)
Run Code Online (Sandbox Code Playgroud)
现在,我的第一个目标是获得以下存储库结构:
A <- B <- C <- N <- O <- P
Run Code Online (Sandbox Code Playgroud)
我在过去几个小时里一直试图做的事情如下:
git diff > /path/to/patch 从叉子里面.git apply 在原始存储库中.A使用将其重置为提交git reset --hard COMMIT_HASH_A. …git ×13
commit ×2
git-rebase ×2
rebase ×2
corruption ×1
git-patch ×1
git-workflow ×1
github ×1
merge ×1
recovery ×1
repository ×1