1

If one developer on a team renames a remote branch that another developer also has checked out, what's the best way for that second developer to update their local repo so they don't accidentally push to the old branch name?

Chris Williams
  • 11,647
  • 15
  • 60
  • 97

2 Answers2

3

As noted by your link, there is no "renaming a branch"; so what the first developer has done is to create a new branch, and then delete the old branch out from under others who were using it[1].

It's possible to update each local repo independently, by manually messing with branch-related config settings and such - or, even more dangerously, by directly hacking the metadata... But I prefer a solution like this:

Given that old-branch-name was deleted and new-branch-name was created to replace it:

1) Fetch and create the new branch locally.

git fetch -p
git checkout new-branch-name

Note the -p argument to fetch, which will cause the remote tracking ref for old-branch-name to go away (since old-branch-name is no longer on the remote).

Assuming new-branch-name wasn't already in use (either in the local repo, or in another of its configured remotes), this creates the new branch with appropriate tracking, and checks it out. Then

git reset --hard old-branch-name
git branch -D old-branch-name

Now, there are a lot of different scenarios that would lead up to this point, and we can walk through any or all of them that might seem concerning, but the bottom line is this makes it look as it would if the branch had always been new-branch-name.

For example if you previously had

x -- A <--(origin/old-branch-name)
      \
       B <--(old-branch-name)

and the origin copy of new-branch-name is still at A, then the fetch -p gives you

x -- A <--(origin/new-branch-name)
      \
       B <--(old-branch-name)

and after the checkout, reset, and branch -D you have

x -- A <--(origin/new-branch-name)
      \
       B <--(new-branch-name)

If the remote copy of new-branch-name had advanced (say, to C), then the fetch would've given you

x -- A -- C <--(origin/new-branch-name)
      \
       B <--(old-branch-name)

and finally you'd have

x -- A -- C <--(origin/new-branch-name)
      \
       B <--(new-branch-name)

which is no different than the normal case where your local branch is behind the remote.

Like I said, there are many scenarios, so if there's one of particular concern feel free to comment and I can add it. But in any case, this should effectively replace the old branch with the new one in whatever state of integration you'd have already had were there no "rename".


[1] This is not to say it's necessarily the wrong thing to do, if it's called for by the team's agreed-upon process; but it does mean that the person doing it should be accountable for communicating the change, with the natural consequence that someone will recreate the branch under its original name - and almost certainly create divergent branches - otherwise.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
1

If you don't have any work in progress on the branch or other reason to save the name, deleting the old name as in Mark Adelsberger's answer is usually the way to go.

If you do have reason to just rename it, you can do it in two commands:

  • rename the branch: git branch -m old-name new-name
  • change the upstream to the new name: git branch --set-upstream-to=origin/new-name new-name

You can do these in the other order, you just have to use the correct name at the time.

torek
  • 448,244
  • 59
  • 642
  • 775