Last active
December 8, 2023 15:12
-
-
Save nerdCopter/8b28147511aca110aa4eb25a5fae45e5 to your computer and use it in GitHub Desktop.
git usage notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
git_notes.txt -- assumes CLI in Linux/OSX or Cygwin or WSL (Windows SubSystem for Linux). | |
https://git-scm.com/docs/ | |
https://www.atlassian.com/git/tutorials/ | |
--- | |
################################################## | |
### Recommended Windows vs Linux Compatibility ### | |
################################################## | |
# recommended git global environment configs: | |
# windows: | |
git config --global core.autocrlf true | |
# linux/osx: | |
git config --global core.autocrlf input | |
# cross-platform: | |
git config --global core.safecrlf warn | |
git config --global core.whitespace cr-at-eol | |
git config --global core.filemode false | |
git config --global help.autocorrect true | |
######################## | |
### BASIC REPO STUFF ### | |
######################## | |
#on CLI, with github 2FA, you will need an ssh-key. create a key one time. you will use it often, or add to scripts if you prefer. | |
ssh-keygen -b 2048 -t rsa -f ~/.ssh/myGitHubKey -q -N "" | |
#now tell GITHUB to trust the key: | |
# go to you https://github.com/settings/keys | |
# create new key, TITLE it your filename or whatever you like ("myGitHubKey") | |
# copy the content of ~/.ssh/myGitHubKey.pub into the KEY field | |
#now when you need to communicate with github via CLI, you need to add the key to your CLI session | |
#but first, very often in Linux you must first "eval" the local ssh-agent. sometimes, not always; use as needed. | |
eval "$(ssh-agent)" | |
#now add you generated key into bash-session, but this will exist only temporarily. | |
ssh-add ~/.ssh/myGitHubKey | |
# you can also specify time to stay alive, so -t 21600 is 6 hours: | |
ssh-add -t 21600 ~/.ssh/myGitHubKey | |
## git status -- use this constantly and consistently if you are CLI. my CLI prompt automatically runs it for me. | |
git status -uno -sb | |
# so you want it in your CLI prompt too? add these lines verbatim the the end of your ~/.bashrc | |
function gitstatus() { | |
if [[ -e .git ]] ; then | |
git status -uno -sb | |
fi | |
} | |
PROMPT_COMMAND=gitstatus | |
#fork a repo on github.com UI (example here EmuFlight) | |
#now clone it to your local PC | |
git clone https://github.com/myUSERNAME/EmuFlight.git | |
cd ~/EmuFlight | |
## on github prefer `email privacy enabled` -- set/get your private/public email from https://github.com/settings/emails | |
git config user.email "56356767+myUSERNAME@users.noreply.github.com" | |
git config user.name myUSERNAME | |
git remote set-url origin git@github.com:myUSERNAME/EmuFlight #change to ssh for CLI pushing | |
git remote add upstream https://github.com/emuflight/EmuFlight.git #can use url because will not push | |
git remote set-url --push upstream disabled | |
git remote -v | |
#you do want to keep your repo in sync as often as possible: | |
#sync personal(origin) repo from official(upstream) repo: | |
git fetch --all | |
git checkout master | |
git pull upstream master | |
git push origin master | |
####################### | |
### BASIC GIT STUFF ### | |
######################## | |
#note: in most cases of `git` you can add `--dry-run` to see what would happen, but not actually do it. | |
#always branch from master (after you're synced) | |
git checkout master | |
git checkout -b myBranch | |
# you can git add specific file or all: | |
# git add src/main/io/osd.c #add a single file | |
# git add -u #add all modded files | |
#of course you need to commit your additions | |
git commit -m "title" -m "description" | |
# push to your repo after your are complelty satisfied. see below for squashing multiple commit to one | |
git push #it will show you what to type if you need to create branch server side | |
#show the recent commits with short commit SHA | |
git log --oneline --decorate=no | head -n 15 #just show 15 of the most recent, skip the "|head" part if you want all | |
git log --oneline --decorate=no 0.3.4..master # useful for seeing what commits you've added since TAG | |
git log --date=short --pretty=format:"%h%x09%an%x09%ad%x09%s" | head -n 30 #git log simple but more info | |
#fix last commit comment | |
git commit --amend -m "new fixed comment" -m "new fixed description" | |
#commit without mods i.e. trigger a build | |
git commit --allow-empty -m "Trigger build" | |
#squash all your WIP commits into one and force push a clean branch | |
git reset --soft <FirstSHAbeforeYourEdits> | |
git add -u | |
git commit -m "your clean message" -m "your clean description" | |
git push --force #overwrite the branch with clean squashed commit. | |
#delete branch | |
git branch -d branch_name #alias for --delete | |
git branch -D branch_name #alias for --delete --force | |
git push -d <remote_name> <branch_name> #--delete local AND remote #e.g. git push -d origin myBranch | |
#git reset single files to prior versions | |
git checkout HEAD -- my-file.txt | |
git checkout HEAD^ -- my-file.txt | |
git checkout HEAD~2 -- my-file.txt | |
git checkout master -- my-file.txt | |
#################### | |
### HOUSEKEEPING ### | |
#################### | |
#list untracked files | |
git ls-files . --exclude-standard --others | |
# clear untracked file | |
# use with caution? | |
git clean -df #delete force | |
#Cleanup unnecessary files and optimize the local repository | |
git gc [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack] | |
# deletes local references to non-existing branches on all remotes. | |
git fetch --prune --progress #same as all of: git remote prune [origin|upstream|etc] | |
# cleanup/housekeeping of local clone | |
git gc --prune --aggressive | |
# cleanup un-referenced | |
git prune --progress | |
# delete local [merged|unmerged] branches not on remote [origin] | |
# just view: | |
git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | |
#when comfortable to delete, pipe the same command to to delete | |
#| xargs git branch -d #for unmerged, use -D | |
#replace origin with upstream as well | |
############################# | |
### INTERMEDIATE GIT STUFF ### | |
############################# | |
#basic diff examples: | |
git diff #implies HEAD | |
git diff --name-only | |
git diff HEAD^ #head minus 1 | |
git diff HEAD~3 #arbitrary number of commit histories | |
git diff HEAD~6 src/js/tabs/led_strip.js | |
git diff <commitSHA> | |
git diff master myBranch | |
git diff <commitSHA> <commitSHA> | |
git diff HEAD^ > ../path/to/DiffFile.diff #pipe diff to a file for later use | |
#diff folders/files examples: | |
git diff HEAD -- src/js/tabs/osd.js | |
git diff HEAD^ -- src/js/tabs/pid_tuning.js | |
git diff myBranch:locales/ HEAD:locales/ | |
git diff myBranch:src/tabs/pid_tuning.html master:src/tabs/pid_tuning.html | |
# diff exclude folder example | |
git diff master..HEAD -- . ':!src/main/target' | |
#applying diff-file examples | |
#it a good idea to review the `--check --stat` before the actual `--apply` | |
git apply --stat --check ../path/to/DiffFile.diff #just check, no apply | |
git apply --stat --check --recount ../path/to/DiffFile.diff #same but recount matching lines in-case of differing(modded) HEAD | |
git apply --stat --check --recount --exclude=src/main/flight/pid.c ../path/to/DiffFile.diff #same , but exclude a file | |
git apply --apply --stat --check --recount ../path/to/DiffFile.diff #apply, but dont commit, allows for manual git add | |
git apply --apply --verbose --stat --check --recount -C 5 --exclude=src/main/flight/pid.c ../path/to/DiffFile.diff #apply but try to match more lines for safety | |
#force reset personal fork master to match upstream master | |
git remote add upstream /url/to/original/repo ## (e.g. https://github.com/emuflight/EmuFlight.git) | |
git remote set-url --push upstream disabled | |
git remote update #update status of remotes | |
git checkout master #switch to your master | |
git reset --hard upstream/master #get upstream master | |
git push origin master --force #push/overwrite your master | |
#add upstream official repo to personal fork | |
git remote add upstream https://github.com/emuflight/EmuFlight.git | |
git remote set-url --push upstream disabled | |
git remote -v | |
## use stuff like this to block pushing | |
git remote set-url --push upstream disabled #if using my own repo w/ official upstream | |
git remote set-url --push origin disabled #if cloned official emu | |
#re-enable upstream pushing, be extremely careful, prereq=ssh/key | |
## if FORKed repo | |
# git remote set-url --push upstream git@github.com:emuflight/EmuConfigurator | |
# git remote set-url --push upstream git@github.com:emuflight/EmuFlight | |
## if CLONE (official) repo | |
# git remote set-url --push origin git@github.com:emuflight/EmuConfigurator | |
# git remote set-url --push origin git@github.com:emuflight/EmuFlight | |
## good idea to disable afterward for protection | |
## example of enabling & pushing branch upstream and disabling: | |
### git checkout -b newBranch | |
### git remote set-url --push upstream git@github.com:emuflight/EmuConfigurator | |
### git push upstream | |
### git remote set-url --push upstream disabled | |
#add a 3rd-party fork to your local repo | |
git remote add somebody_fork <url of fork> | |
git remote -v #show remote status before disabling push | |
git remote set-url --push somebody_fork disabled | |
git remote -v #show remote status after disabling push | |
git fetch somebody_fork | |
git checkout --track somebody_fork/branch_name | |
# pull someone else's pull-request (PR) | |
# git checkout -b NewBranch master | |
# git pull git://github.com/USERNAME/EmuFlight.git PRBRANCH | |
git checkout -b Kaiowarez-crsf-lq master | |
git pull git://github.com/Kaiowarez/EmuFlight.git crsf-lq | |
git checkout -b 20201120_build_tylercorleone_mixer_smoothing master | |
git pull git://github.com/tylercorleone/EmuFlight.git mixer_smoothing | |
#braching or cherry-picking somebody_fork examples | |
git checkout -b my_test_branch somebody_fork/<branch> | |
git checkout master ; git checkout -b myNewBranch ; git cherry-pick --no-commit somebody_fork/someAtomicBranch #... | |
#git cherry-pick works often, but sometimes not and needs mods. | |
#so retain authorship with commits: | |
git commit --amend --author="Pawel Spychalski <pawel.spychalski@raisin.com>" --no-edit | |
git commit --author="Quick-Flash <46289813+Quick-Flash@users.noreply.github.com>" -m "all the flight stuffs" -m "QF the prodigious" | |
git commit --author="Kaiowarez <60309480+Kaiowarez@users.noreply.github.com>" -m "Kaio fixing the targets" | |
git commit --author="Tom Hensel <80815+gretel@users.noreply.github.com>" -m "thanks Tom" | |
git commit --author="loutwice <loutwice@gmail.com>" -m "Loutwice patience keeping us sane" | |
git commit --author="Robert Marinus <bubi-007@hispeed.ch>" -m "technical filtering stuff" | |
git commit --author="nerdCopter <56646290+nerdCopter@users.noreply.github.com>" -m "backported code from XYX" | |
git commit --author="Andrey Semjonov <50518855+AndreySemjonov@users.noreply.github.com>" -m "fixing iTerm like King Kraken" | |
git commit --author="BeauBrewski <85623381+BeauBrewski@users.noreply.github.com>" -m "TargetMaster3001" -m "Co-authored-by: nerdCopter <56646290+nerdCopter@users.noreply.github.com>" | |
git commit -m "commit message" -m "Co-authored-by: another-name <another-name@example.com>" | |
git commit -m "commit message" -m "Co-authored-by: Andrey Semjonov <50518855+AndreySemjonov@users.noreply.github.com>" | |
git commit -m "commit message" -m "Co-authored-by: Kaiowarez <60309480+Kaiowarez@users.noreply.github.com>" | |
git commit -m "commit message" -m "Co-authored-by: BeauBrewski <85623381+BeauBrewski@users.noreply.github.com>" | |
git commit -m "commit message" -m "Co-authored-by: nerdCopter <56646290+nerdCopter@users.noreply.github.com>" | |
# How to use two masters from separate remotes: | |
# Given repo `alpha` and repo `beta`, and assuming local repo is clone of `alpha`: | |
git checkout master | |
git remote add beta https://gitlab.com/someAccount/someRepo | |
git fetch --all | |
git checkout -b beta_master beta/master | |
# There you have beta's remote master stored locally as `beta_master`. | |
# From now on, you may: | |
git fetch --all | |
git checkout beta_master | |
git pull beta master | |
# Of course you may use your own naming conventions. (e.g replace `beta` with `gitlab`.) | |
########################## | |
### REPAIRING PROBLEMS ### | |
########################## | |
#find conflict sections | |
grep -Iirn -P "[>=<][>=<][>=<][>=<][>=<][>=<][>=<]" src/ | |
#git authentication problems fixes | |
#assuming CLI with SSH keys being used. set to ssh, not url | |
# when using 2FA and CLI, ssh and an ssh-key is required. once you have a key, you can add it in your shell session: | |
eval "$(ssh-agent -s)" #shell/cli usually works without eval, but needed at least when you ssh from another machine, or the agent memory is lost | |
ssh-add ~/.ssh/myGitHubkey #always add you key to your session | |
# Now you can set your repo/upstream/forks to ssh | |
git remote set-url origin git@github.com:USERNAME/FORKNAME #set your origin(personal fork) for ssh | |
# git remote set-url upstream git@github.com:emuflight/EmuFlight #set upstream(official repo) for ssh | |
# git remote set-url FORKNAME git@github.com:USERNAME/FORKNAME #set some remote for ssh | |
#fix failing to find/pull branches | |
git config --get remote.origin.fetch ## may show botched: +refs/heads/master:refs/remotes/origin/master | |
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" #this is the fix | |
git config --get remote.origin.fetch ## will show fixed: +refs/heads/*:refs/remotes/origin/* | |
git remote update #now update | |
# -or- | |
git fetch --all | |
#now pull | |
git pull BRANCH | |
# -or- | |
git pull --all | |
# when it's really broke, and you want to reset to upstream/origin's branch of choice [master] | |
git fetch origin master | |
git reset --hard FETCH_HEAD | |
git clean -df #-x if you want folders too, but you will have to rebuild. e.g. ./downloads/* ./obj/* ./tools/* | |
# reopen closed PR after a force push | |
# https://gist.github.com/robertpainsi/2c42c15f1ce6dab03a0675348edd4e2c | |
############ | |
### TAGS ### | |
############ | |
git tag tagName #create tag at current commit | |
git tag --delete tagName #delete local tag | |
git push --delete [origin|upstream] tagName #delete local | |
## horrible idea (don't do it), but... push all tags: | |
## git push --tags | |
######################################################### | |
### EmuFlight Specific Build System | |
### as per https://github.com/emuflight/EmuFlight/pull/552 | |
######################################################### | |
git checkout [master|branch|commit] | |
git tag buildTag | |
git push [upstream|origin] buildTag | |
git tag --delete buildTag | |
git push --delete [upstream|origin] buildTag | |
``` | |
GitHub Actions for Draft-Releases to dev-unstable and dev-master, or Release to Official Repo. | |
* All tags build to GH-Actions artifacts. | |
* Tag names containing substring `releas` will draft-release to emuflight repo. | |
* Tag names containing substring `unstab` or `test` will draft-release to dev-unstable repo. | |
* Tag names containing substring `master` will draft-release to dev-master repo. | |
* tag could potentially contain all of the above substrings for draft-release to multiple repos. | |
* Removes defunct JFrog BinTray uploading. | |
* Tags will build (building now requires tagging). Should delete tag afterward. | |
* Forks can use tags as well for personal repo gh-actions artifacts. | |
* tagname examples: that will draft-release to target repos: forTesting, releaseThis, stableMaster, ReleaseMasterAndUnstable | |
* How to: | |
git checkout [master|branch|commit] | |
git tag buildMe | |
git push [origin|upstream] buildMe | |
git tag --delete buildMe #delete local tag | |
git push --delete [origin|upstream] buildMe #delete remote tag | |
``` | |
############# | |
### STYLE ### | |
############# | |
# recommended code format restyling | |
sudo apt install astyle | |
astyle --style=attach --indent=spaces=4 --pad-oper --convert-tabs --preserve-date --suffix=none --mode=c --delete-empty-lines --recursive ./src/*.c | |
astyle --style=attach --indent=spaces=4 --pad-oper --convert-tabs --preserve-date --suffix=none --mode=c --delete-empty-lines --recursive ./src/*.h | |
############### | |
### CREDITS ### | |
############### | |
#many ways to do these things | |
git shortlog --email --summary --numbered | |
git log --pretty=format:'%an' | sort -f | uniq -i | |
git log --all --pretty=format:'%an' | sort -f | uniq -i | |
git log --pretty=format:'%h - %an <%ae>, %ar : %s' 313a9d5...HEAD | |
git log --pretty=format:'%an <%ae>' 313a9d5...HEAD | sort | uniq | |
git log --all --pretty=format:'%an' c28ca22f955...HEAD | sort -f | uniq -i | |
# co-auth credits: | |
git log --follow --pretty=format:'Co-authored-by: %an <%ae>' -- src/main/drivers/accgyro/accgyro_spi_icm426xx.c | sort | uniq ## credits per file | |
############ | |
### TIPS ### | |
############ | |
#DzikuVx: 1 - for new stuff always create a new branch from current master and just code and commit into it | |
#DzikuVx: 2 - if you want to do something else, checkout master, pull and create a new branch | |
#DzikuVx: 3 - when you feel that your feature branch is somehow outdated and it needs a refresh: checkout it, do a fetch of origin (or upstream) and finally just git merge master | |
#DzikuVx: as a result you land in exactly the same state as if you merged your feature to master and started all over or applied some diff above master | |
#DzikuVx: http://paul.stadig.name/2010/12/thou-shalt-not-lie-git-rebase-ammend.html | |
#DzikuVx: https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow | |
############ | |
### MISC ### | |
############ | |
Stargazers: https://github.com/ACCOUNT/REPO/watchers | |
useful aliases:
alias gl='git log --oneline --decorate=no | head -n 15'
alias gs='git status -uno -sb | less'
alias contains='git branch -r --contains' #usage: contains SHA
in ~/.bashrc
Delete local and origin branch:
~/.bashrc
contains:
function branchdelete() {
if [ -z "$1" ] ; then
echo "no branch specified."
echo "permanently deletes specified local branch and origin/branch"
else
git branch -D "$1"
git push --delete origin "$1"
fi
}
EmuFlight Specific Build System
as per emuflight/EmuFlight#279 , we generally build/compile/draft-release like this:
git checkout [BRANCH]
git tag someDescriptiveTagName
git push [upstream|origin] someDescriptiveTagName
git tag --delete someDescriptiveTagName
git push --delete [upstream|origin] someDescriptiveTagName
Therefore, another useful function for your CLI shell (~/.bashrc
) is:
function tagbuild() {
if [ -z "$2" ] ; then
echo "usage: tagbuild someDescriptiveTagName [origin|upstream]"
else
## EmuFlight Specific Build System
# as per https://github.com/emuflight/EmuFlight/pull/279
git tag "${1}"
git push "${2}" "${1}"
git tag --delete "${1}"
git push --delete "${2}" "${1}"
fi
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Automatically show git status in directory of repo (but limit the results -- see aliases below):
~/.bashrc
contains: