Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As I understand the situation, someone has pushed commits to <code>master</code> in your central repository (<code>origin</code>) that you don't want there, and you want to (a) fix this on your local repository and then (b) push the fixed branches back to the central repository. <a href="https://stackoverflow.com/questions/5395509/moving-commits-to-new-branch-removing-from-current-branch-on-pushed-repo/5395600#5395600">adymitruk's answer</a> tells you how to force push the master branch - part (b) - but it's worth saying a little about (a) as well. The final, and most awkward, consideration is (c): how the other people who are using the repository will deal with the rewritten <code>master</code> branch.</p> <p>Firstly, I think it's worth considering whether it would be OK to just revert the commits that shouldn't be on master. This option will cause the least disruption to the other people who have already pulled from <code>master</code> and give you less work in explaining to people how do deal with the result - part (c). However, if you've decided that you mustn't have those commits followed by reverts in the <code>master</code> branch then here are the steps you should take:</p> <h3>(a) Fixing master locally</h3> <p>This bit is pretty easy. As usual with git, make sure that git status is clean. Then:</p> <pre><code># Make sure you're on master: git checkout master # Create a branch at this point for the commits that your co-worker should # have put on a topic branch: git branch ill-advised-experiment # Reset your master branch to the last good commit: git reset --hard &lt;SHA1-OF-LAST-GOOD-COMMIT&gt; </code></pre> <h3>(b) Pushing the revised master and topic branch</h3> <p>Your master now doesn't contain the complete history that's in origin's master, so you have to "force push":</p> <pre><code>git push -f origin master </code></pre> <p>... but you can push the new topic branch as usual, of course:</p> <pre><code>git push origin ill-advised-experiment </code></pre> <h3>(c) Letting other people know what they should do</h3> <p>The risk after you've force-pushed a rewritten <code>master</code> branch is that someone has already done a <code>git pull</code> or <code>git pull --rebase</code>, so they have the accidental commits in their master branch. If that person then pushes to <code>master</code> on <code>origin</code>, the bad commits will be back in the <code>master</code> branch and you're back to square one. So, supposing the earliest bad commit has the object name (SHA1sum) <code>f414f3l</code>, you can ask people to check:</p> <pre><code>git branch -a --contains f414f3l </code></pre> <p>If they get an error, then that commit isn't in their repository at all, and it's all fine.</p> <p>If they see that <em>only</em> the <code>origin/master</code> remote-tracking branch contains that commit, again it's all easy - they should just run <code>git fetch origin</code> to update their remote-tracking branch.</p> <p>However, if both <code>master</code> and <code>origin/master</code> contain that commit, the user needs to be a little more careful. Firstly, the user should stash or commit all their work, to make sure that <code>git status</code> is clean. Then I would suggest the following:</p> <pre><code># Leave a branch pointing to your old master, just to make it easy to find # commits from there: git checkout master git branch old-master # Now update all the remote-tracking branches from origin (you should see # a "forced update" message for master): git fetch origin # Now reset the master branch to the right remote version: git reset --hard origin/master </code></pre> <p>Now, if this user only had a few unstaged and uncommitted changes, they can then just <code>git stash apply</code> and carry on.</p> <p>If they'd just done one or two new commits, it's probably easiest to find the object names of those commits from <code>git log old-master</code> and do <code>git cherry-pick &lt;SHA1sum-OF-MY-COMMIT&gt;</code> for each one. Then they can carry on as normal.</p> <p>Finally, if they'd done a lot of commits, it's probably easiest to use an interactive rebase to apply those commits onto the new master, and skipping the bad commits. That would involve:</p> <pre><code># To be extra cautious, create a new branch based on "old-master" for # rebasing and switch to that: git checkout -b old-master-for-rebasing old-master # Start an interactive rebase: git rebase -i master # At this stage, delete every line that refers to a bad commit or anything # that shouldn't be in master now. Leave everything else in the file, as # a line beginning with "pick". # If all went well, this branch can now be merged into master, which should # be a fast-forward merge: git checkout master git merge old-master-for-rebasing </code></pre> <p>I hope that's of some use.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload