6

I've somehow got some duplicate commits in a branch, each with the same changes. It's a public branch, merged from several branches by several users. I need to periodically rebase this branch onto the master branch of another repo, and these duplicates make it clumsy.

Is there a way to remove these and push them to the public repo w/out making it complicated for other users working from the branch?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
michael
  • 346
  • 4
  • 12
  • 1
    Assuming that you regard recovering from history rewriting (i.e. rebasing everything from the original public branch onto the new one) as complicated, no, there is no way to do this. Removing commits is rewriting history. – Cascabel Apr 26 '11 at 20:16
  • 2
    Are you sure you have duplicate commits _on the same branch_? Seems to me the only real way this can happen is by first rebasing and later merging the previously rebased branch. However, the merge will not be fastforward, and the merged commits will technically be 'from the merge' not 'from the branch' (i.e. when following first parents only, a log would not show the commits). Does that make sense? – sehe Apr 26 '11 at 21:04
  • I think sehe is right - you gotta make sure they are on te same branch. "rebase -i" should clarify that momentarily, as the OP will be able to see right away if the problem really exists as described – Eugene Sajine Apr 27 '11 at 15:16
  • Yes, they're on the same branch now, I can see them in git log. gitx shows them coming from different branches originally. I don't know how this happened, but no doubt I screwed something up along the way to do this - am slowly getting used to git. In the past I have rebased the branch onto a master branch from another repo and then pushed it up to the public repo. There are three identical commits, each has the same changes. I checked by creating a patch for each from its parent commit and they showed the same changes. When I try interactive rebase, they all show up. – michael Apr 27 '11 at 17:28

2 Answers2

5

filter-branch is not necessary in this case IMHO and as Jefromi mentioned without making life a bit complicated for everybody else it is impossible. First rule of Git - do not rewrite published history.

If you really want to cleanup the branch that has got messed up, then you should rebase it locally, rearrange commits and force-push it to mainline if needed.

in order to do that (imagine that the branch is checked out locally and the last known good state after which you have started to get those duplicates is 20 commits ago)

git checkout yourPublicBranch
git rebase -i HEAD~20

This will fire up the editor in which you will be able to manage the commits. Then you will have to save the file and exit for rebase to start working. That may lead to conflicts.

Eugene Sajine
  • 8,104
  • 3
  • 23
  • 28
  • I know how to do interactive rebasing to get rid of the commits. I can force it to the public repo if I have to. What do users have to do after that to get in sync? If they haven't made any changes to their local copies of the branch I know (?) they can just pull the new branch and be fine. But if they're made their own local changes in the meantime?? Thanks. – michael Apr 27 '11 at 17:33
  • 1
    You need to notify them that the history has been rewritten for this branch. Then they have to: 1."git fetch remoteName" - this will update remote-tracking branches and will notify them about forced update on the branch of interest 2. if they have no local changes in this branch, they can just pull and it will be overwritten. If they do have changes in local brach that is tracking this rewritten one, they can do "git pull --rebase", so their local changes will be rebased on top of new history. If they have other branches that were spawned from this public one they will have to rebase them too. – Eugene Sajine Apr 27 '11 at 17:39
  • Great, thanks. I didn't realize it could be as simple as them doing "git pull --rebase". Fingers crossed that that will take care of it. – michael May 02 '11 at 19:03
0

Use git filter-branch to rewrite the history. Here's a good intro from github:

http://help.github.com/removing-sensitive-data/

rtn
  • 127,556
  • 20
  • 111
  • 121
  • A key part of the OP's question is "without making it complicated for other users" - and that's essentially impossible. They will always have to take some steps to recover from the rewriting of history. – Cascabel Apr 26 '11 at 20:15