1st Question: How can I move (4.) to a different branch? After much web searching I tried doing "git branch doc; git reset HEAD <sha of commit (3.) above>" but this did absolutely nothing, local directory still has all above changes.
git reset handles 3 things at once: 1) the commit history, 2) the staging area, 3) the working tree (local directory). Its default mode of operation ("mixed") is that it un-commits and un-stages your changes, but does not remove them fully.
| mode | resets |
--soft | only the commit (changes remain in files and staged, merely un-committed) |
--mixed (default) | commit and staging area (changes remain in files but are unstaged) |
--keep | commit, staging area, and files (changes disappear) |
--hard | commit, staging area, and all files (all changes disappear – even pending ones that weren't part of the commit) |
Remember to take a look at git status after doing the reset.
In your situation, reset --keep would have been more useful. (Alternatively --hard is also fine if you don't have any unstaged changes that you want to keep.)
But after doing a "mixed" reset like you've done, you can still just use git checkout -f <somefile> to discard changes from a specific file.
2nd Question: FOSS project advises that when a PR is submitted they like to see just one commit in the PR. After solving the above issue, how can I rebase or ??? my fork so it will show as only one commit in the PR? Thank you
First, stop making unnecessary pulls/merges like you did in steps 2 and 5. You really don't need to repeatedly git pull unrelated new stuff into your PR branch. (That's one reason why a separate branch is recommended from the beginning, instead of working on 'main/master' directly.)
That would be my first complaint before I got to being picky about the docs change. (I'd say the number of 'real' commits is much less important; a bunch of little commits is good when working – they can be squished into one after the fact.)
Take a look at it using gitk or tig – a branch that has one real commit and five merges is a mess to handle. So try to keep your PR branches to only the commits necessary to make the change you want to make and nothing more. If you want to always work "on top of" the latest version, then consider git pull --rebase instead.
Second, if the upstream repository is on GitHub, they literally have a "Rebase" button to squish the whole PR into one single commit as part of accepting the PR. But if they're asking you to do this, then the most common way is git rebase, specifically its fixup or squash operations.
There is a one-line git rebase --onto or something command to do a "flattening" rebase in a single step but I can never remember it, so the full process is:
To start with, figure out what your "base" branch actually is. If you had been working on a separate branch, then the base would likely have been your local 'main' or 'master'. But if you're working on main directly, then you might only have 'origin/main' or 'upstream/main' as a usable base (depending on which way your remotes go in git remote). If you've changed your remotes so that you only have your fork – you might not have a base branch anymore; re-add the upstream repository with git remote add -f.
Take a quick look at the commits between that base and your branch with gitk BASE.. or tig BASE.. or something like git log --graph --oneline.
It's a good idea to do a "plain" rebase without any actions, just to make sure it goes through without conflicts (especially when merges were involved, as rebasing will get rid of them).
git rebase THE_BASE_BRANCH
Then take a look at the results with the aforementioned tools again. Probably a good idea to look at the commit diffs and verify that they're still changing what you intended to change.
Now that the branch has been re-based on top, rebase --interactive can be used to rearrange commits with less risk of conflicts.
git rebase -i THE_BASE_BRANCH
In the list that opens, if you change the 2nd commit from pick to fixup, it will be combined into the commit above. So in order to get just one commit, change all except 1st to 'fixup'.
You will have to push --force the rewritten history into your PR branch (in this case don't try to pull even if Git suggests that, or you'll just undo all the cleaning up you've just done).
Though if you end up with conflicts, there are more direct ways to create a new single-commit branch without going through 'git rebase'. For example, you could start a new clean branch off the base, then manually copy in your files and commit them.