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"?
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.
If the origin still the same you can rename your local branch to keep working with the version on Github.
- Make sure you're in
master
branch
git checkout master
- 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
© 2022 - 2024 — McMap. All rights reserved.