1140

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?

2

7 Answers 7

1527

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.

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

15 Comments

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
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 :)
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.
For example, to push everything but the last commit with some standard names git push origin HEAD~1:master.
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.
|
164

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 be 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

7 Comments

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'?
@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.
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.
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.
@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.
|
29

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.

1 Comment

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.
28

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.

4 Comments

Could you perhaps give a move complete example esp. re the git log step?
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.
+1 Did you ever encounter the "wrath of the git gods" after rebase-push-rebase? (Could conceivably happen also by accident, right?)
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.
22

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} 

5 Comments

git revert is a bad idea here -- it creates a new commit
@hasen: You could then just cherry-pick the commit you want.
both revert and cherry-pick are bad ideas. git rebase -i is your friend here, see answer from Walter Mundt below.
@Nicolas, why is cherry-pick a bad idea?
@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.
10

The simplest way to accomplish this is with two commands.

First, get the local directory into the state that you want. Then,

git push origin +HEAD^:someBranch

removes the last commit from someBranch in the remote only, not local. You can do this a few times in a row, or change +HEAD^ to reflect the number of commits that you want to batch remove from remote. Now you're back on your feet, and use

git push origin someBranch

as normal to update the remote.

2 Comments

Great answer. Very clean way to change the HEAD of a remote branch without affecting the local branch. I recently accidentally pushed a few commits to remote that were WIP commits. This was by far the easiest way to get the remote back to its previous state. Nice one.
As far as accidental pushes this technique requires that you can force push to the remote something that is not always allowed by the remote.
2

You could also, in another directory:

  • git clone [your repository]
  • Overwrite the .git directory in your original repository with the .git directory of the repository you just cloned right now.
  • git add and git commit your original

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.