How do I update my GitHub mirror due to the master/main change?
Asked Answered
G

2

5

I mirrored a GitHub project years ago. This project participated in the grand "master"-to-"main" branch renaming. I haven't touched my fork in a while, and I have a branch in my fork, and a local copy of my fork. But my fork and special branch are based off when the source project used "master"! How can I transition my fork to use "main," including syncing to the source's "main"?

Gastrula answered 31/10, 2020 at 3:22 Comment(0)
B
6

Branch names, in Git, have no real meaning and can be changed at any time. So some of the work, though this is only the easy part, is to just enter your own clones and rename their master to main.

including syncing to the source's "main"?

We'll leave that for last.

Terminology note

A "fork" on GitHub is essentially a clone with some extra features. I'll use the term "fork" to refer to the GitHub clone from here on, and the term "clone" or "your clone" to refer to the local one.

Instructions that assume you didn't have a clone already

(These instructions are here for others: you mentioned you already have a local clone.)

GitHub do not offer a way to rename branches directly, so if you want to rename a branch in your fork, you must first clone that to your own machine locally:

git clone --no-checkout <url>

(where url is one of ssh://[email protected]/name/repo.git, [email protected]:name/repo.git, or https://github.com/name/repo.git for instance) to make a local clone on your own machine. You'll need to have Git installed, for that machine. Note: we're using --no-checkout so that your new clone has no branches yet. You have all the commits, and no branches.

Enter the clone you've just made:

cd repo

for instance. Your clone will have a remote-tracking name, origin/master, that you can use to create a new name in your GitHub clone:

git push origin origin/master:main

Your GitHub fork now has two different names for the same commit: both master and main. You can now delete the GitHub fork's master, either through the web interface, or through the command line:

git push origin --delete master

Since we created this clone with --no-checkout, we can now just run:

git checkout main

to create the branch name main locally, with origin/main set as its upstream.

Instructions that assume that you do have a local clone

Your local clone probably already has a master. Let's make sure it is up to date with your fork:

cd my-local-clone
git fetch origin                  # if needed
git checkout master               # if needed
git rebase origin/master          # if needed
git branch -m master main

Now we just need to create the name main on GitHub, the same as in the examples above—but we'll use the local main to do that, since that's a bit shorter:

git push -u origin main && git push origin --delete master

We get to use the -u option to update our local main to refer to origin/main, which accomplishes everything except deleting the name master in the fork (see footnote 1 above), so we do that with a separate step.

You may want, now, to use GitHub's web interface to change the main branch name in your fork

I'm not sure if GitHub have anything smart that might do this automatically when you delete the name master. My guess is that they don't. (I have not tried it yet with any of my forks.) This web page also implies that they don't. You'll need to go into the settings page and choose main as the default branch.

Once you've done that, it's not a bad idea to use git remote set-head to update your local clone:

git remote set-head origin --auto

which will make your origin/HEAD reflect the new origin/main setting.

(All of these are optional, they just make some non-fatal but odd error cases go away.)

Updating your fork

It's now time to update your own fork. This is the hard part, because:

I haven't touched my fork in a while, and I have a branch in my fork ...

You must decide here exactly what you want to update, and how. The key to keep in mind is that Git does not care about branch names. It only cares about commits. Use git log --graph, or some commit-graph-viewer, to view the commits and their relationships with each other.

You need a name for the fork that is upstream from your fork—the GitHub clone you used when you made your GitHub fork. A standard name for this is upstream. (I think this name is a bit confusing, since each branch can also have an upstream set, and it's a little odd to talk about the upstream setting of branch X and also talk about what's on the remote named upstream, but let's run with that for now.)

You may already have a name for this. Use git remote or git remote -v to view your existing remote names. Assuming you only have origin and mean to add upstream, use git remote add to create upstream:

git remote add upstream <url>

where url is the GitHub URL for their fork. Then run:

git fetch upstream

to obtain any new commits from them, and create your own upstream/main and other remote-tracking names in your clone.

You can now merge, fast-forward, rebase, or otherwise update your main. If you're not already on your own main:

git checkout main    # or git switch main

Now run git merge --ff-only upstream/main, or git rebase upstream/main, or whatever it is you might like to do here. If you want to toss any main (old master) commits that you have, that they don't—there may not be any such commits, in which case merge or rebase will all do the same thing as this will—you can use:

git reset --hard upstream/main

No matter which of these you use, your own local main name now identifies the same commit as your upstream/main: the same commit that the upstream fork identfies with their name main. Now you can update your GitHub fork:

git push origin main    # add --force if needed and desired

You will only need the --force option if you are discarding some commit(s) in this process.

You must then make the same kinds of decisions about your own branch. Do you want to keep any commits you have that they don't? Do they have a branch with this name at all, and if so, is it related to your branch with this name? (Every repository has its own branch names, and there's no requirement that they be used the same way.)

Assuming they haven't dropped any commits—if they have, your Git will now think that these commits are your commits and will try to use them as part of your branch—you may now be able to rebase your branch, whatever its name is, on your own main:

git checkout xyzzy
git rebase main

If they have dropped some commits, you may need git rebase --onto so as to keep those commits out of your update; see other StackOverflow questions to see how to do this.

There may be merge conflicts while copying your commits, depending on how much they have changed their code. If so, you'll have to resolve them. If there are a lot of large conflicts, I recommend saving the original set of commits by creating a new branch name for your old branch-tip commit before you start the rebase operation:

git checkout xyzzy
git branch xyzzy.0
git rebase main

When you're done with the rebase, you will have xyzzy.0 (your original commits as they appeared before) and xyzzy (your new-and-improved commit copies). If things went wrong during the rebase, it's relatively easy now to go back and look at your original commits.

Either way, you can now use:

git push -f origin branch

to send the new commits to your GitHub fork and make your GitHub fork Git repository use the name branch to identify the new-and-improved commits from the rebase. It's up to you whether to create the name branch.0 on your fork as well, to keep access to the original commits there.

Bazil answered 31/10, 2020 at 7:0 Comment(1)
Invaluable stuff. I'm sorry I can upvote only once.Constructivism
R
0

If the origin still the same you can rename your local branch to keep working with the version on Github.

  1. Make sure you're in master branch

git checkout master

  1. Rename the branch

git branch -m main

Then you'll be able to continue work with as before but with main branch instead of master

Ridgley answered 31/10, 2020 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.