The following is a list of notes on git/GitHub workflow tasks that I don't do often enough to remember implicitly.
Keeping the name as something like upstream is probably a best practice
git remote -v
git remote add upstream <path to upstream repo>
git checkout <local branch name>
git fetch upstream <branch name>
git merge upstream/<branch name>
NOTE: Be mindful here if you are working with multiple local and upstream branches, ie
master
andfuture
. For example, it's really easy to accidentally merge upstreamfuture
into localmaster
.
git diff upstream/master origin/master --name-only
git checkout upstream/future -- docs/breaking_changes.md
git diff > my.patch
git diff upstream/master origin/master > my.patch
git apply my.patch
Often useful when there are conflicting changes you want to ignore:
git apply --reject --whitespace=fix my.patch
git reset --hard upstream/<branch name>
git push origin <branch name> --force
- This is extremely dangerous and the potential for loss of work is high. Plan ahead before running this command.
- Make sure you have merged the origin/upstream master and have a clean working directory.
- If you are planning to rewrite a GitHub repo, it is also recommended you make a fresh clone of it into a different directory for verification and recovery purposes.
- Run:
git rebase --interactive --root
NOTE: Using the
--root
arg is a big time saver if you want to rebase all history. Otherwise, you must pass in args to pick and choose as needed.
- As you cycle through the list of commits, pick the ones you want to squash, typically all of them but the top.
You might need to resolve merge conflicts withgit add
andgit rebase --continue
.
NOTE: A rebase replays the list of commits over the current working branch, so the theirs and ours are flipped, so in the case of a rebase, ours means the master. If you want to try to skip merge conflicts, you can try:
git rebase --interactive --root -X ours master
NOTE:
git commit --amend
is handy here if you just want to rewrite the last commit message instead of re-running rebase.
- Once the local history looks the way that you want it to (use
git logs
to check it), it's time for the most dangerous step. You should hopefully have a backup copy that you made in step #2, and please don't get in the habit of using--force
. This will take your local commit history and overwrite the GitHub repository's history to match. Then, once others subsequently do a git pull, their version lineage will be rewritten to match it.
git push --force
- Verification (optional). Go to the backup of the repository you made in step #2, and remember not to get latest. Then simply do a
git diff origin
to confirm that the rewritten history matches the previous contents of the repo.
git checkout --theirs -- <filename>
git reset --soft HEAD~3 && git commit --edit -m'blah' && git push --force
Where 3 is the number of commits back in history to squash.
- Install GPG using
brew install gpg
or similar based on your OS. - Add an alias to your .gitconfig file that associates
git ci
tocommit -S
- Add the following git configuration:
git config --global user.signingkey
where signingkey is the public key signature of the GPG key.
Configure git to store GitHub creds in local OS store
git config --global credential.helper store
These are GPG commands that I rarely if ever need to run and therefore often forget. In order to import a GPG key from one machine to the other, simply run:
gpg --import <path.to.private>.key
In order to change the passphrase of a private key:
gpg --edit-key <key-id>
passwd
# ...
save
In order to list the currently installed keys:
gpg --list-keys