在git中,是否可以逐个推送提交而不是一次性推送所有提交?

7

我正在使用一条非常不可靠的连接。尽管我试图分阶段提交以避免任何一个提交超过20MB并等到它们达到这样的大小再推送,但有时不可能(一些资产可能很大 - 我知道在git中也使用资产不是最好的想法),有90%的机会在所有内容发送之前我的连接会失败。

有没有可能逐个推送提交,或者您可以提供任何其他有用的提示吗?


问题:你知道提交只保存它和上一个提交之间的更改吗?添加了一个10 MB文件的10个提交并不等于100 MB。如果您更改了该10 MB文件的一行,git将仅存储该行更改的记录。 - Jacobm001
出于好奇...你在你的git仓库中存储了什么如此庞大的东西? - Jacobm001
2个回答

13

是的,这不仅可能而且实际上相当简单。只需要将:

git push remote branch

只需运行:

git push remote <commit-hash>:branch

为了尝试推送,每个提交都需要执行一次,并按适当的(从父级到子级)顺序执行。

要自动完成此操作,假设您的远程存储库名为origin,分支名为branch,并且您的origin/branch远程跟踪分支已经是最新的(如果不是,请运行git fetch origin):

for rev in $(git rev-list --reverse origin/branch..branch); do
    git push origin $rev:branch;
done

这实际上是一行代码为了在StackOverflow上发布而分成三行的。 (注意:这还假定一个更或多或少线性的历史记录;如果不是,请添加--topo-order来保证事情,但是那样你就需要使用--force 并且会出现各种糟糕的想法,所以不应该采取这种方式:您需要拆分推送以使用临时分支,或在合并点处聚合它们,也许。)


如果这是一个在远程不存在的新本地分支,那该怎么办? - Steven Shaw
1
@StevenShaw:在这种情况下,您必须手动选择起始提交。我们在<exclude>..branch表达式中使用origin/branch,因为我们知道它是远程已经拥有的提交,所以第一个git push从该点之后可达的第一个提交开始,这可能是origin缺少的第一个提交。一旦找到适当的起始点,您可以使用git push创建origin/branch,或者手动创建它,之后上面的代码片段将起作用。 - torek
1
如果不清楚(我不确定):origin/branch是一个本地名称,它保存了您自己Git中关于远程branch的记忆。如果我们没有它,我们就不能使用它*。我们可以用多种不同的方式创建它。我们只需要它来启动整个过程,所以如果您的连接可靠 - 如果您不必经常重新启动这一系列git push-es,您可以只写for rev in $(git rev-list --reverse <hash>..branch); do ...。但是,如果您的连接可靠,则首先根本不需要任何内容。 - torek
谢谢,我已经将“from”切换为origin/master,如git rev-list --reverse origin/master..branch。唯一的问题是远程分支不存在,因此git push会失败,因为远程引用不存在。我不知道如何创建一个“空”的远程分支,而不推送我的本地分支(这将打败逐个推送提交的目的)。 - Steven Shaw
2
@StevenShaw:origin/master通常可以使用,但可能需要强制推送才能启动“真正”的提交。git merge-base origin/master branch是更好的起点:git push -u origin $(git merge-base origin/master branch):refs/heads/branch将在您的本地存储库中创建origin/branch并将其设置为branch的上游,之后一个一个地推送就可以了。 - torek

3

仅为澄清其他答案:

git push <remote name> <commit SHA>:<remote branch name>

例子:

git push origin c01c4fa28a0c864c2d09f8fb43a80c46dce9c7c6:master

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