我将一个Bazaar存储库导入Git(使用git bzr
),但生成的存储库包含一个虚假的提交父链接:
请注意,标记为1.02-6
的提交基于1.02-3
提交,但1.02-1
也不必要地标记为父级。 (注意:repo的这一部分中的所有提交都被标记;显示的提交之间没有提交。)
我尝试过几种方式的变基(在master
分支上:git rebase 1.02-3
,git rebase -i upstream-1.02
,git rebase --onto 1.02-1 1.02-3
,git rebase --root upstream-1.02 --onto=other_branch
),但在每种情况下都是合并冲突失败。这似乎是在尝试超过必要的;历史记录正确除了,在提交标记1.02-6
中记录了额外的父指针。
如何删除链接以便对历史进行线性化?有没有比按顺序手动挑选所有提交更好的方法?
答案 0 :(得分:16)
最简单的方法(使用git> = 1.6.5)是使用:
def simple_cull(inputPoints, dominates):
paretoPoints = set()
candidateRowNr = 0
dominatedPoints = set()
while True:
candidateRow = inputPoints[candidateRowNr]
inputPoints.remove(candidateRow)
rowNr = 0
nonDominated = True
while len(inputPoints) != 0 and rowNr < len(inputPoints):
row = inputPoints[rowNr]
if dominates(candidateRow, row):
# If it is worse on all features remove the row from the array
inputPoints.remove(row)
dominatedPoints.add(tuple(row))
elif dominates(row, candidateRow):
nonDominated = False
dominatedPoints.add(tuple(candidateRow))
rowNr += 1
else:
rowNr += 1
if nonDominated:
# add the non-dominated point to the Pareto frontier
paretoPoints.add(tuple(candidateRow))
if len(inputPoints) == 0:
break
return paretoPoints, dominatedPoints
def dominates(row, candidateRow):
return sum([row[x] >= candidateRow[x] for x in range(len(row))]) == len(row)
import random
inputPoints = [[random.randint(70,100) for i in range(3)] for j in range(500)]
paretoPoints, dominatedPoints = simple_cull(inputPoints, dominates)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dp = np.array(list(dominatedPoints))
pp = np.array(list(paretoPoints))
print(pp.shape,dp.shape)
ax.scatter(dp[:,0],dp[:,1],dp[:,2])
ax.scatter(pp[:,0],pp[:,1],pp[:,2],color='red')
import matplotlib.tri as mtri
triang = mtri.Triangulation(pp[:,0],pp[:,1])
ax.plot_trisurf(triang,pp[:,2],color='red')
plt.show()
并删除/添加/更改Parent:行。
一旦你感到高兴,改变是正确的,你可以重写提交以使改变永久化:
git replace --edit <sha>
答案 1 :(得分:5)
您可以使用git commit-tree
内部命令手动执行此操作。
我们要编辑提交标记1.02-6
以删除虚假父指针(56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4
)。
首先,从现有提交对象中读取信息:
user@host:/path/repo.git$ git cat-file -p 1.02-6
tree c658aa1ebcf2bf2a607696c7868b875be72fb01f
parent 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4
parent 4e671bf1d2298729c9e5cfd8229051cfe2c40831
author James Damour (Suvarov454) <suvarov454@users.sourceforge.net> 1146319620 -0400
committer Bazaar Package Importer <james.westby@ubuntu.com> 1146319620 -0400
The "main/" in the Section line of debian/control should be assumed.
Extract the commit message using git log --format=%B -n 1 1.02-6
.
现在创建一个具有相同内容的新提交(不包括虚假父链接和提交者信息):
git log --format=%B -n 1 1.02-6 | \
GIT_AUTHOR_NAME="James Damour (Suvarov454)" \
GIT_AUTHOR_EMAIL="suvarov454@users.sourceforge.net" \
GIT_AUTHOR_DATE="1146319620 -0400" \
git commit-tree c658aa1ebcf2bf2a607696c7868b875be72fb01f \
-p 4e671bf1d2298729c9e5cfd8229051cfe2c40831
这创建了一个新的提交,并打印了它的哈希值(cc32e66
...)。现在把它变成一个新的分支:
git checkout -b fixed_commit cc32e66
并将master
重新加入新分支:
git checkout master
git rebase fixed_commit
我们已经完成了:
您可能希望删除旧分支并重新标记相应的提交。
实际上使用git filter-branch --parent-filter
可能更容易。我没试过。
答案 2 :(得分:2)
这将纠正父母而不改变任何其他内容(例如提交者日期):
git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of 1.02-6] && echo "-p [sha of 1.02-3]" || cat' -- 1.02-1..master
您必须使用适当的提交ID替换括号内的文本。如果您有更多需要重写的下游分支,请将1.02-1..master
更改为--all
并准备等待。
当然,如果其他人已经在您要编辑的提交之后的任何提交中分支,请不要使用此解决方案或任何其他解决方案。他们会讨厌你。
答案 3 :(得分:1)
您可以尝试rebase。有一个例子有点下来(搜索--onto),我认为这与你的情况类似。
我认为你需要做
git rebase --onto 1.02-1 1.02-3
应该将1.02-3之后的所有内容放到1.02-1上,这可能是你想要的。
请记住,哈希在第一次更改提交时的所有内容都会有所不同,但我认为你这样做是作为从bzr迁移的第一步,所以没有其他人应该克隆它。