views:

3541

answers:

5

I have the branch master which tracks the remote branch origin/master.

I want to rename them to "master-old" both locally and remote. Is that possible? For other users who tracked origin/master (and who updated their local master branch always just via 'git pull'), what whould happen after I renamed the renamed the remote branch. Would their 'git pull' still work or would it throw an error that it coudln't find origin/master anymore?

Then, further on, I want to create a new master branch (both locally and remote).

Again, after I did this, what would happen now if the other users do the 'git pull' now?


I guess all this would result in a lot of trouble. Is there a clean way to get what I want? Or should I just leave master as it is and create a new branch master-new and just work there further on?

+2  A: 

I'm assuming you're still asking about the same situation as in your previous question. That is, master-new will not contain master-old in its history.* If you call master-new "master", you will effectively have rewritten history. It does not matter how you get into a state in which master is not a descendant of a previous position of master, simply that it is in that state.

Other users attempting to pull while master does not exist will simply have their pulls fail (no such ref on remote), and once it exists again in a new place, their pulls will have to attempt to merge their master with the new remote master, just as if you merged master-old and master-new in your repository. Given what you're trying to do here, the merge would have conflicts. (If they were resolved, and the result was pushed back into the repository, you'd be in an even worse state - both versions of history there.)

To answer your question simply: you should accept that sometimes there will be mistakes in your history. This is okay. It happens to everyone. There are reverted commits in the git.git repository. The important thing is that once we publish history, it is something everyone can trust.

*If it did, this would be equivalent to pushing some changes onto master, and then creating a new branch where it used to be. No problem.

Jefromi
Yea, it's the same problem, just was one idea how to solve it. But even if I would not do this branch-renaming, I was interesting if it would be possible.I thought such refs as "master" are only references to specific commits. I really don't want to change any history. I thought I would just point the master-reference to another head.This also means, I can never ever use a branch name again if I have ever used it before?
Albert
Indeed, branches are refs - pointers to commits. The thing is, we expect the head of a branch to evolve in a particular way (namely, always fast-forwarding). From the point of view of someone else, moving a branch in your public repo is the same as rewriting the history of the branch. It no longer points to a commit containing everything it used to.
Jefromi
+9  A: 

The closest thing to renaming is deleting and then re-creating on the remote. You can do this by eg:

git branch -m master master-old
git push remote :master # delete master
git push remote master-old # create master-old on remote
git checkout -b master some-ref # create a new local master
git push remote master # create master on remote

However this has a lot of caveats. First, no existing checkouts will know about the rename - git does not attempt to track branch renames. If the new master doesn't exist yet, git pull will error out. If the new master has been created. the pull will attempt to merge master and master-old. So it's generally a bad idea unless you have the cooperation of everyone who has checked out the repository previously.

bdonlan
Ok, thanks for the explanation. Then I probably don't that. :) (I wasn't sure if perhaps Git would be intelligent enough to know that the branch was renamed.)
Albert
branches are just a (name, hash) pair - nothing more, nothing less. There is the reflog on branches, but this is never exposed to remote clients.
bdonlan
I would create master-old on remote before deleting master on remote. I'm just paranoid.
adymitruk
A: 

git update-ref newref oldref

git update-ref -d oldref newref

dlamotte
A: 

What about:

git checkout old-branch-name
git push remote-name new-branch-name
git push remote-name :old-branch-name
git branch -m new-branch-name
pht
A: 

Assuming you are currently on master:

git push origin master:master-old        # 1
git branch master-old origin/master-old  # 2
git reset --hard $new_master_commit      # 3
git push -f origin                       # 4
  1. First make a master-old branch in the origin repository, based off of the master commit in the local repository.
  2. Create a new local branch for this new origin/master-old branch (which will automatically be set up properly as a tracking branch).
  3. Now point your local master to whichever commit you want it to point to.
  4. Finally, force-change master in the origin repository to reflect your new local master.

(If you do it in any other way, you need at least one more step to ensure that master-old is properly set up to track origin/master-old. None of the other solutions posted at the time of this writing include that.)

Aristotle Pagaltzis