How can I push a specific commit to a remote, and not previous commits?

635,938

Solution 1

To push up through a given commit, you can write:

git push <remotename> <commit SHA>:<remotebranchname>

provided <remotebranchname> already exists on the remote. (If it doesn't, you can use git push <remotename> <commit SHA>:refs/heads/<remotebranchname> to autocreate it.)

If you want to push a commit without pushing previous commits, you should first use git rebase -i to re-order the commits.

Solution 2

The other answers are lacking on the reordering descriptions.

git push <remotename> <commit SHA>:<remotebranchname>

will push a single commit, but that commit has to be the OLDEST of your local, non-pushed, commits, not to be confused with the top, first, or tip commit, which are all ambiguous descriptions in my opinion. The commit needs to the oldest of your commits, i.e. the furthest from your most recent commit. If it's not the oldest commit then all commits from your oldest, local, non-pushed SHA to the SHA specified will be pushed. To reorder the commits use:

git rebase -i HEAD~xxx

After reordering the commit you can safely push it to the remote repository.

To summarize, I used

git rebase -i HEAD~<number of commits to SHA>
git push origin <post-rebase SHA>:master

to push a single commit to my remote master branch.

References:

  1. http://blog.dennisrobinson.name/push-only-one-commit-with-git/
  2. http://blog.dennisrobinson.name/reorder-commits-with-git/

See also:

  1. git: Duplicate Commits After Local Rebase Followed by Pull
  2. git: Pushing Single Commits, Reordering with rebase, Duplicate Commits

Solution 3

I'd suggest using git rebase -i; move the commit you want to push to the top of the commits you've made. Then use git log to get the SHA of the rebased commit, check it out, and push it. The rebase will have ensures that all your other commits are now children of the one you pushed, so future pushes will work fine too.

Solution 4

Cherry-pick works best compared to all other methods while pushing a specific commit.

The way to do that is:

Create a new branch -

git branch <new-branch>

Update your new-branch with your origin branch -

git fetch

git rebase

These actions will make sure that you exactly have the same stuff as your origin has.

Cherry-pick the sha id that you want to do push -

git cherry-pick <sha id of the commit>

You can get the sha id by running

git log

Push it to your origin -

git push

Run gitk to see that everything looks the same way you wanted.

Solution 5

I believe you would have to "git revert" back to that commit and then push it. Or you could cherry-pick a commit into a new branch, and push that to the branch on the remote repository. Something like:

git branch onecommit
git checkout onecommit
git cherry-pick 7300a6130d9447e18a931e898b64eefedea19544 # From the other branch
git push origin {branch}
Share:
635,938
Robert23
Author by

Robert23

Updated on May 04, 2022

Comments

  • Robert23
    Robert23 about 2 years

    I have made several commits on different files, but so far I would like to push to my remote repository only a specific commit.

    Is that possible?

  • hasen
    hasen almost 14 years
    git revert is a bad idea here -- it creates a new commit
  • Josh K
    Josh K almost 14 years
    @hasen: You could then just cherry-pick the commit you want.
  • dminer
    dminer over 12 years
    git push <remotename> <commit SHA>:<remotebranchname> works. the trick is to combine it with git rebase -i to move the commit you want as the first commit, and specify that commit-sha
  • vedang
    vedang about 12 years
    @dminer's comment needs a lot more upvotes. I think you should edit the answer to show git rebase -i dminer.
  • estan
    estan about 12 years
    another good tip is to make sure you copy the SHA of the commit you want to push after doing that rebase -i, and not before, like i just did :)
  • Nicolas C
    Nicolas C almost 12 years
    both revert and cherry-pick are bad ideas. git rebase -i is your friend here, see answer from Walter Mundt below.
  • jefffan24
    jefffan24 almost 12 years
    Keep in mind that this fails if the remote branch does not yet exist. Creating the branch can be done with git push <remotename> <commit SHA>:refs/heads/<new remote branch name>. After this, push as the answer describes.
  • artless noise
    artless noise about 11 years
    For example, to push everything but the last commit with some standard names git push origin HEAD~1:master.
  • Drux
    Drux over 10 years
    Could you perhaps give a move complete example esp. re the git log step?
  • Adam Smith
    Adam Smith over 10 years
    Say you have 3 relatively independent commits with messages "A", "B", "C" committed in that order and you want to push "B". 'git rebase -i' should get you and editor listing all three; move B up and save/quit. 'git log --pretty=oneline -n3' will list B, A, C with hashes before each message, with B now last. 'git checkout -b temp $hash_of_B; git push' ought to push B at that point. You'll then probably want to 'git checkout -b master; git branch -d temp' to get back to your previous state, presuming you were on your local master branch; replace as applicable.
  • Drux
    Drux over 10 years
    +1 Did you ever encounter the "wrath of the git gods" after rebase-push-rebase? (Could conceivably happen also by accident, right?)
  • Adam Smith
    Adam Smith over 10 years
    If you read my answer carefully, you see that the push only happens after the rebase, and the rebased commit is only moved above other commits that were not yet pushed. Once a commit is pushed, it should generally be considered set in stone; leave it alone in future rebasing. This technique is only so you can sort out multiple local changes into a good ordering before pushing them. If you have tracking set up correctly, 'git rebase -i' with no other args will default to not even showing you pushed commits, so it's safer from accidents than some other methods.
  • Antoine
    Antoine about 10 years
    @Nicolas, why is cherry-pick a bad idea?
  • Nicolas C
    Nicolas C about 10 years
    @Antoine, typically you want your branch to stay in sync with the one it tracks on origin. If you cherry-pick, you're doing a copy/paste, and you'll have to deal with the not pushed copy at some point. If you rebase -i, you do "cut and paste", and keep your branch in sync with the remote up to where you want it to be.
  • Ian Vaughan
    Ian Vaughan about 10 years
    Also note, that if you have already pushed a later SHA to that remote branch, then you will need to force push this one. Use the -f flag.
  • Vinay Bhargav
    Vinay Bhargav over 9 years
    Using git rebase -i will be ideal solution as suggested in above solutions. Cherry pick must be used only when you want to duplicate the commit.
  • Ed Avis
    Ed Avis over 8 years
    Some origins may not allow this, it seems. For example with GitLab I see 'You are not allowed to force push code to a protected branch on this project.'. Which is a little odd since I didn't think I was forcing anything, just doing a normal push. Any idea how to do it without 'forcing'?
  • Samuel
    Samuel over 8 years
    @Ed Shoudln't be any need to force push. Sounds like you have an issue with your specific git setup. Perhaps you rebased past the remote HEAD commit? I don't know what a protected branch is, sounds like a permission issue.
  • Ed Avis
    Ed Avis over 8 years
    Samuel - that would make sense, but git rebase -i only shows you the local commits which are later than the remote HEAD, so I don't know how I could have done that.
  • Ed Avis
    Ed Avis over 8 years
    Samuel - indeed I can do partial pushes now so I don't know what went wrong but it must have been trying to push a commit not derived from remote HEAD one way or another.
  • Samuel
    Samuel over 8 years
    @Ed You said "git rebase -i only shows you the local commits which are later than the remote HEAD", I don't think this is true. I tested and was able to rebase past the remote HEAD.
  • Ed Avis
    Ed Avis over 8 years
    When you run 'git rebase -i' it shows you only a certain set of commits: 'the same set of commits that would be shown by git log <upstream>..HEAD', according to the documentation. I thought this meant that whatever you did to those commits, you wouldn't be able to go further back than the upstream HEAD, but I guess it must be more subtle than that.
  • Ivandro Jao
    Ivandro Jao over 7 years
    What happen if we don't specify heads e.g: refs/<branch-name>?
  • galath
    galath over 7 years
    @estan nitpicking: instead of writing the SHA of the commit, create a tag with git tag <tag_name> before git rebase -i ; then, when you are done, clean with git tag -d <tag_name>
  • Rufus
    Rufus about 7 years
    why doesn't git push <remotename> <commit SHA> push to the current branch by default, just like how git push does...?
  • Pencilcheck
    Pencilcheck almost 7 years
    Not sure if this answers the question but it is useful to what I want to do (rollback changes on heroku for instance)
  • jaques-sam
    jaques-sam over 5 years
    Funny that for such a simple thing, such a difficult command must be used. In Mercurial, it's just hg push -r <REV>
  • Paul Stelian
    Paul Stelian over 4 years
    @Ed It's the last fetched upstream HEAD, not how it is right now (if it updated after the last fetch) that is considered by rebase -i.
  • Eduardo Pignatelli
    Eduardo Pignatelli over 4 years
    And you can use git log origin/master..master to check the SHAs of all the commits you haven't pushed to remote - stackoverflow.com/questions/3080509/…
  • Mukul Anand
    Mukul Anand almost 3 years
    i think such answers could help more with an example
  • Robert Monfera
    Robert Monfera over 2 years
    What if I don't want to type in the <remotebranchname>? It's a tracking branch I'm on, so it should be possible to infer