有没有一种简单的方法将一个源代码树的一系列tarballs转换成git仓库?

12
我对git不熟悉,但我有许多长期运行项目的每周tarballs,每个tarball平均有几百个文件。我正在寻找一种git策略,使我可以将每个tarball的扩展内容添加到一个新的git存储库中,从版本1.001开始,经过版本1.650。在项目的这个阶段,99.5%的tarball(n)只是版本(n-1)的副本 - 换句话说,它非常适合使用git。期望的最终结果是在此过程结束时仅剩下主分支。
我认为我足够了解git以手动完成此操作。我理解的是,没有合并冲突的可能性,因为在添加和提交下一个版本之前不可能更改主分支。我的第一个猜测是shell脚本,但是我不确定当处理git checkout branch_n时bash正在执行branch_n-1时bash会喜欢它。对于该项目,主机环境为Ubuntu 10.4,可用资源为8 Gig RAM,500 Gig空闲磁盘空间和4个3.ghz的CPU处理器。
我不需要别人解决问题,但我可能需要一个指引,告诉我git专家会如何解决它。来自已经“走过”这条路的人的任何建议都将不胜感激。

所有答案都指出分支不应该是必要的。然而,您可能想创建标签,这些标签是指向给定提交的固定指针,经常用于标记版本号。 - Cascabel
5个回答

9
请查看 $GIT_SRC_DIR/contrib/fast-import/import-tars.perl

1
http://git.kernel.org/?p=git/git.git;a=blob;hb=HEAD;f=contrib/fast-import/import-tars.perl - Jakub Narębski
Stefan, 好建议!!Perl不是我最喜欢的脚本语言,但它确实验证了一般方法并指出了一些潜在问题,如果我在tarball中有符号链接的话。 我需要按特定顺序应用更新以获得所需结果,但这将是一个很好的基准。 import-tars似乎还依赖于我不熟悉的fast-import- 但这是另外一个故事。 - Hotei
1
@Hotei:import-tars.perl是一个示例脚本;它用于演示如何使用快速导入接口。您可以使用自己喜欢的脚本语言编写自己的脚本(在Python的contrib/fast-import中有一个示例import-zips.py)。 - Jakub Narębski

4

关于这条评论:

我不确定当bash在执行branch_n-1时,git checkout branch_n会得到多少支持。

您是否担心两个操作同时运行并相互干扰?除非您有意并行运行操作,否则这不应该是问题。

假设tarball遵循线性演化,分支根本不涉及其中。

该过程应该非常简单:

  1. git init
  2. untar ball _n_
  3. git add --all .; git commit(使用适当的标志)
  4. git tag -a v1.001 -m "Version 1.001."
  5. rm -rf *(处理历史记录中的删除;当然要保留.git)
  6. 转到步骤2

也许“担心”不是正确的词。如果git从bash中移出$PWD,我很“不确定会发生什么”。 <detour> 也许bash不会这样做,但很久以前我模糊记得读过sh在某个地方创建正在执行的命令的副本作为文本文件,然后随着脚本的执行修改该文本文件。如果这种情况不在$PWD中,那就没问题了。 </detour> - Hotei
回到你之前的问题 - 不,我并不打算并行运行它,因为我希望结果是一个按时间顺序排序的合并行,然后可以使用类似gitg的工具浏览。 - Hotei
我喜欢你的建议,并在评论中结合了上面的一个建议。 - Hotei
已经在前三个tarball上测试了解决方案,看起来它正在做我想要的事情。编写脚本应该相对简单。感谢所有提供帮助的人。 - Hotei
2
你可以在 commit 命令中加入 --date 选项,并使用归档的原始日期,将该信息记录到 git 历史记录中。 - hfs

3
在这种情况下,我会按照以下步骤进行操作,因为您有一些以“标记版本”结尾的tarballs:
  1. 创建一个空的git仓库
  2. 将tarball解压缩到该目录中,覆盖任何文件
  3. 添加所有文件 git add .
  4. git commit -a -m 'version foo'
  5. git打上当前版本的标签
  6. 删除所有文件
  7. 为每个tarball重复从步骤2开始执行
在您的情况下,不需要创建分支,因为您的所有tarballs都是不同的、连续的版本;每次迭代都会覆盖之前的版本。

1
你漏掉了一步 - 在倒入tarball之前删除先前的内容。 - Cascabel
真的,已将其添加到列表中。否则删除操作将无法处理。 - Marcin Gil
我称它们为版本,但实际上它们并不完全是版本。更像是“快照编号”。我通常每一两个月才会进行一次真正的版本更新。 - Hotei
我因为提到git标签步骤而点了个赞。我需要能够回退并检出早期的提交,我相信标签会让我轻松做到这一点。 - Hotei

1

如果你没有确切地在那里,你应该简单地:

  • 在任何你想要的地方解压一个存档文件
  • 将其与git工作目录同步,以便:
    • 更改相关文件
    • 从该存档中添加新文件到工作目录
    • 从工作目录中删除不再是当前存档一部分的文件
  • git add -A
  • git commit -m“archive n”
  • 重复

这个想法不是检出branch_n+1,而是保持在同一个分支内,在同一个git repo的同一个分支中逐个提交每个tar内容。
如果你真的有两个并行的进程,那么你可以:

  • git clone第一个git repo
  • git branch -b a_new_branch确保你将并行进程隔离在自己的分支中,当完成后你将能够将其推回第一个repo。

1
我喜欢这个想法,但是将前两个答案结合起来可能会更容易。到目前为止,看起来像是: git init 将tarball(n)解压缩到新的repos中 git add -A git commit -m“版本号foo” rm -rf *(但不包括.git) 重复 - Hotei

0

看一下git-weave。你可以将包含所有扩展tarball的目录和一个包含它们之间序列和连接(它处理分支)以及提交消息的log文件提供给它,它会从中创建一个git存储库。

在你的情况下,有大约600个tarball,这看起来是一个艰巨的任务,你可能需要编写一个脚本来拼凑log文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接