在Git中提交根提交之前添加提交?

Bra*_*one 16 git backup commit github

新问题

两个问题:

  1. 我试图在所有提交之前提交一个提交.
    最底层的提交有660fb2a76211f36ec9a67d0454a90eab469e9fd0SHA.当我输入git rebase -i 660fb2a76211f36ec9a67d0454a90eab469e9fd0每个提交但最后一个提交显示在列表中.
    我真的需要这个提交出现所以我可以把第一个提交作为最后一个!

  2. 当我把第一个提交作为第一个提交在列表中时(意思是第二个提交总共,因为第一个提交不在上面提到的列表中)我得到一个错误:error: could not apply b722c76... v1.4.3 BEAT release
    我只是从列表的底部剪切并放入它到顶部!我没有改变号码!
    我也试了好几次.同样的结果.

到目前为止就是这样.如果您有疑问请继续问!

原始问题

我刚刚发现了我项目的旧备份.这些备份是在我使用git之前创建的.
我现在想将它们作为旧提交添加到我的存储库中.这意味着我必须将这些提交放在所有其他提交之前.

现在有几个问题:

  1. 我如何在其他人之前提交一个提交?
  2. 我怎么能这么快?(我有很多备份!)
  3. 如何为这些"旧"提交设置日期?(我知道备份的日期!)

如果不清楚,请提及.我会解决这个问题!

最后一件事:

我已经在GitHub上发布了这个.我主要使用他们的软件来提交提交.那我怎么把它推回GitHub呢?

小智 13

更新

我发现了另一个稍微简单的方法,使用--root标志git rebase.我用我的回购试了一下,所以我知道它有效(至少对于一个完全线性的历史,最后更多关于它).

第1步:创建repo的备份克隆

让我们安全地进行备份,以防我们最终做出灾难性的事情并丢失您的数据:

git clone original-repo backup-repo
Run Code Online (Sandbox Code Playgroud)

第2步:创建孤立分支(这将是您的新根)

检查孤儿分支.指定一个起始点提交/分支是可选的,如果你保留该参数,那么Git将默认使用你当前的提交作为起点(它遵循标准分支语法的模式):

git checkout --orphan new-master firstCommitOfOldMaster
Run Code Online (Sandbox Code Playgroud)

我将旧主服务器的根目录指定为起点,因为它可能会更快地执行以下步骤(删除工作目录文件).

第3步:删除工作目录文件

new-master从旧主服务器创建孤立分支可能会在工作目录和索引中留下文件,具体取决于您分支的提交中文件的状态:

调整索引和工作树,就像之前运行一样git checkout <start_point>.这允许您启动一个新的历史记录,记录一组类似于<start_point>通过轻松运行git commit -a以进行根提交的路径.- git checkout docs

你现在要做的是彻底清除分支的状态,这样你就可以从一个干净的平板(从顶级文件夹运行)中重新开始:

git rm -rf .
Run Code Online (Sandbox Code Playgroud)

这是文档的解释:

如果要启动记录一组完全不同的路径的断开连接的历史记录<start_point>,则应通过git rm -rf .从工作树的顶层运行创建孤立分支后立即清除索引和工作树.之后,您将准备好准备新文件,重新填充工作树,从其他地方复制它们,提取tarball等.

第4步:重新开展较早的工作 new-master

现在你要开始将你的旧作品提交到new-master.当你完成后,你将把你的老主人变成最重要的.

我不确定你的备份文件夹是如何组织的,但我将假设每个文件夹只是项目文件夹的日期副本,以YYYY-MM-DD格式命名,例如2013-01-30.您可以手动将每个文件夹的内容添加为新提交,也可以编写脚本以自动执行该过程.

假设您将所有备份文件夹放在一个名为的顶级文件夹中,该文件夹backup与主项目文件夹位于同一目录中.然后,这里有一些脚本的伪代码,用于自动执行提交每个文件夹的过程:

# Get backups and sort them from oldest to newest
backups = open("backups").toList().sort("date ascending")
for each (backup in backups)
    copy files from backup to project folder
    execute `git add "*"`
    execute `git commit --date="#{backup.date}" --message="#{backup.date}"`
Run Code Online (Sandbox Code Playgroud)

上面的脚本只会在提交之间添加和修改文件.如果您的任何备份已删除,移动或重命名文件,则脚本将不会记录该文件.您需要编写一个更聪明的脚本来执行此操作(可能使用git diff某些其他差异工具),或手动记录这些更改.

第5步:调整基线旧masternew-master

珍惜真棒的真棒! 现在我们要重温您的整个历史! 背诵这些神秘的权力话语,观察魔法的发生!:

git rebase --onto new-master --root master
Run Code Online (Sandbox Code Playgroud)

TA-DA!您可能必须解决最后提交new-master和第一次提交之间的冲突master,但除此之外,应该是它!

解决我们之前遇到的问题的--root标志rebase- 通常 - rebase不会在Git仓库的第一次(根)提交上运行.该--root标志基本上告诉Git将其包含在rebase:

重新引用可以访问的所有提交<branch>,而不是使用<upstream>.这允许您在树枝上重新定义根提交.当与之一起使用时--onto,它将跳过已经包含的更改<newbase>(而不是<upstream>),而没有--onto它将在每次更改时运行.- rebase docs

步骤6:验证最终提交是否仍然相同

为了确保我们没有弄乱任何代码,我们想要master在我们做之前将当前的最终状态与其状态进行比较rebase.以下命令中的任何一个都可以工作(它们是相同的).在master分支上:

git diff orig_head   # "Original" head
git diff master@{1}  # Master at its 1st prior position
Run Code Online (Sandbox Code Playgroud)

如果你没有输出diff,那么这意味着你的最终状态master与之前相同rebase.做得好!

注意:不确定合并提交会发生什么...

现在,如果您有完美的线性历史记录,上述步骤将正常工作,即您没有任何合并提交.如果你这样做,我不确定它是否仍然有用.在我之前的回答中,我提到使用--preserve-merges标志rebase可能会帮助您保留这些合并,但文档提到该标志还与--onto--root标志交互:

当[ --root是]与两个一起使用--onto--preserve-merges,所有根提交将被重写为具有<newbase>作为父代替.- rebase docs

我现在还不确定这意味着什么...我可能要试一试,看看会发生什么.这是否意味着如果你有超过1个root提交(例如10个),那么这些root提交中的9个最终会被重新定位到作为新root的最后一个提交?这似乎不是我们想要的行为.我们只想保留一个root被重新绑定到另一个root的合并提交.


以前的答案

MGA有正确的想法rebase.我不确定这是否能解决您的问题,但也许您需要在您的仓库中进行新的根提交,将备份文件添加为新的提交,然后在旧的提交图上重新设置.

例如,根据文档git checkout有一个--orphan标志:

--orphan <new_branch>
创建一个名为<new_branch>,启动<start_point>并切换到它的新孤立分支.在这个新分支上进行的第一次提交将没有父项,它将成为与所有其他分支和提交完全断开的新历史的根.

所以也许你可以试试

git checkout --orphan <temp_branch>
Run Code Online (Sandbox Code Playgroud)

然后将备份文件提交给它.然后temp_branch检查出来,做

git cherry-pick <first commit from master>
git rebase --onto temp_branch <first commit from master> master
Run Code Online (Sandbox Code Playgroud)

我想你可能需要cherry-pick第一次提交,因为第二个参数 rebase --onto是你要重新绑定的分支的旧基础(在这种情况下master),并且不包括旧的基数.所以这就是为什么我认为你需要cherry-pick它才能得到它,因为它本身没有基本提交,所以你不能在它中为它指定一个rebase.

另请注意,如果您的提交历史记录不是线性的(即它具有合并提交),那么rebase通常不会保留它们.它有--preserve-merges一面旗帜,但我以前从未使用它,所以我不确定它是如何工作的.来自文档:

-p
--preserve-merges
而不是忽略合并,尝试重新创建它们.

这在--interactive内部使用机器,但--interactive明确地将它与选项结合起来通常不是一个好主意,除非你知道你在做什么(见下面的BUGS).

那么,也许所有这些都有效?


归档时间:

查看次数:

6503 次

最近记录:

11 年,6 月 前