10

I'm using a really unreliable connection and while I try to stage commits so none of them is over 20mb and/or to push them once they reach a size like that, sometimes it's not possible (a few of the assets can be big - I know it's not the best idea to use git for assets too) and there are 90% of chances my connection will fail before everything is sent.

Is it possible to push commits one by one, or can you suggest any other tips that could be useful for this case?

2
  • Question: You do know that a commit only saves the changes between it and the previous commit right? 10 commits where you added one 10 MB file does not equate to 100 MB. And if you change one line of that 10 MB file, git will store a record of only that line changing. Commented Jul 18, 2017 at 1:18
  • Out of curiosity... What are you storing in your git repo that is so large? Commented Jul 18, 2017 at 1:18

2 Answers 2

18

Yes, it's not only possible but in fact pretty trivial. Instead of:

git push <remote name> <branch name>

just run:

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

once for each commit to try pushing, in the appropriate (parent to child) order. For example:

git push origin c01c4fa28a0c864c2d09f8fb43a80c46dce9c7c6:branch

To automate this, assuming your remote is named origin and your branch is named branch and your origin/branch remote-tracking branch is up to date (run git fetch origin if not):

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

which is basically a one-liner. Note that this also assumes a more or less linear history. If it's not, add --topo-order to guarantee things, but then you'll need --force and there are various bad ideas occurring here, so that's not the way to go. You'd want to split the pushes to use a temporary branch, or aggregate them at the merge points, perhaps.

Sign up to request clarification or add additional context in comments.

5 Comments

What if this is a new local branch that doesn't exist on the remote?
@StevenShaw: in that case, you must choose your starting-point commit manually. We're using origin/branch above in the <exclude>..branch expression because we know it's a commit that the remote already has, so that the first git push starts with the first commit reachable after that point, which is probably the first commit that origin lacks. Once you have found the appropriate starting point, you can either use git push to create origin/branch, or create it manually, after which the above code fragment will work.
In case that wasn't clear (I'm not sure): origin/branch is a local name that holds your own Git's memory of branch on the remote. If we don't have it, we can't use it yet. We can use it once we create it. We can create it in multiple different ways. We only need it to kick off the whole process, so if your connection is reliable—if you don't have to restart this series of git push-es frequently—you could just write for rev in $(git rev-list --reverse <hash>..branch); do .... But if your connection is reliable, you don't need any of this in the first place.
Thanks, I had switch the "from" to origin/master as in git rev-list --reverse origin/master..branch. The only problem was that the remote branch did not exist so the git push would fail because the remote ref didn't exist. I don't know how to create an "empty" remote branch without pushing my local branch (which would defeat the purpose of pushing commits 1-by-1).
@StevenShaw: origin/master will often work, but might require a force-push to get the "real" commits started. git merge-base origin/master branch would be a better starting point: git push -u origin $(git merge-base origin/master branch):refs/heads/branch would create origin/branch in your local repository and set that as the upstream of branch, after which the one-by-one pushes will work.
4

Just to clarify the other answer:

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

Example:

git push origin c01c4fa28a0c864c2d09f8fb43a80c46dce9c7c6:master

2 Comments

I've amended this answer with the one you wanted to clarify. Consider removing this answer
I know this is an older answer, but if you want to amend an existing answer please edit it instead of adding a new non-answer as an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.