63

Say I made several commits and wish to cherry pick which ones I push to the remote repository. How can I do that (in ascii: C1->C2->C3->C4 and I want to push C2 and C4). Will reordering with rebase, resetting, pushing and then resetting work? (C1->C2->C3->C4 => C2->C4->C1->C3 => reset C4 => push => reset C3). Is there a nicer way?

IttayD
  • 28,271
  • 28
  • 124
  • 178
  • Yes, you can rewrite history (or create separate branch with required history) and then push. This is the only way. – Jakub Narębski Nov 24 '09 at 10:17
  • 3
    Me also was looking for the same issue. This resource might be useful https://miteshshah.github.io/linux/git/how-to-push-single-commit-with-git/ – Adil Aliyev Dec 30 '15 at 02:31

4 Answers4

102

You may be looking for:

git push origin $commit:$branch

Credit: http://blog.dennisrobinson.name/push-only-one-commit-with-git/

Explanatory notes:

  • Pushing a commit pushes all commits before it (as Amber said). The key is to reorder your commits first (git rebase -i), so they are in the order you want to push them.
  • $commit doesn't have to be a sha1. For example, "HEAD~N" would push everything before the last N commits.
  • $branch (typically "master" or "main") is the branch you push to – the remote branch. It does not have to be the same as a local branch.
  • If you need to get some commits out of the way locally, you can use the cherry-pick method (suggested by midtiby) to move them onto a separate local branch first. But as shown here, it's not necessary to create a local branch for the purpose of pushing to a remote branch. You can work on multiple branches at once if you are careful about which commits you push where.

If the remote branch does not exist yet, and you want to create it, it must be prefixed with refs/heads/ (to disambiguate branch from tag):

git push origin $commit:refs/heads/$branch

And as a variation of this theme, deleting a remote branch can be thought of as pushing no commit to it:

git push origin :$branch

Pro tip: git-revise is a tool for massaging your commit stack into shape before pushing. It has a similar interface to git rebase. This tool is irreplaceable (correct me if I'm wrong) for sufficiently hard commit untangling jobs, though its interface is in dire need of replacement.

mbomb007
  • 3,788
  • 3
  • 39
  • 68
user2394284
  • 5,520
  • 4
  • 32
  • 38
27

If you have your commits on a private branch, you can cherry pick commits from the private branch and apply them to the official branch. At this point you can now push all your commits on the official branch (which is the subset that you previously cherry picked).

midtiby
  • 14,550
  • 6
  • 34
  • 43
  • 3
    Or if you commits were on the official branch you can cherry pick into a temporary branch and push it to the remote official branch. ummm...right? – andho Apr 12 '11 at 04:22
  • IMHO The simplest and most usable technique. – Benj Apr 25 '17 at 13:07
13
$ git push <remote name> <commit hash>:<remote branch name>

# Example:
$ git push origin 2dc2b7e393e6b712ef103eaac81050b9693395a4:master
Nikhil Thombare
  • 1,058
  • 2
  • 11
  • 26
3

IIRC, due to how git considers commits to work, C4 inherently includes C3, so the concept of "pushing C4 but not C3" doesn't make sense to git (and likewise C2 relative to C1). (See the answer to this previous question.)

Community
  • 1
  • 1
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 2
    Untrue! C4 references C3 as its parent, but the other answer is more correct: you can cherry pick commits out of the history and apply them to different parents. – Dan Fitch Nov 27 '09 at 16:35
  • Isn't it more like C4 inherently applies it's changes to C3 but C4's changes are it's own. – andho Apr 12 '11 at 04:26
  • 8
    Using `git cherry-pick` on `C4` to apply it to a different branch will not result in `C4` on the new branch, but rather `C4'`, a different (but similar) commit. If someone later merged in the branch with `C4` on it, issues might arise. – Amber Apr 14 '11 at 16:24