Common workflow for mnost cases
Solo workflow
git add .
git commit -m "message to describe change"
git push origin master
Team workflow
git pull origin main # update local main branch
git switch -c <branchname> # checkout new branch for changes to make
git add .
git commit -m "nice little message"
git push origin <branchname>. # put to new branch, not main
Open a pull request on github
Once approved, click Merge on github
Delete my feature branch and repeat with new branch for next change
There are 4 levels of git configuration, from most general to most specific
The more specific config's override the more general ones.
git config --get defaults to local, but if you're not in a repo, it will go to the next level up, ie global
git config --add defaults to local. Will error out if you attempt to add when not in a git repo
git config --add --global can be used in or out of a repo
git config --list list all settings for a repo
git config --list --global list all global settings for user. Stored ~/gitconfig/
git config --list --local list local settings. Stored ./git/config
git config list starting in Git 2.46
git config --unset <key> to delete a key
Set the default branch. Even if you are going to leave it at the current default of Master, set it anyway, otherwise you get a warning about it everytime you init a repo.
git config --global init.defaultBranch master
You can have multiple keys of the same value.
git config --add cocko.name "Craig"
git config --add cocko.name "Cuntos"
git config --add cocko.name "Wanker"
git config list
//
cocko.name=Craig
cocko.name=Cuntos
cocko.name=Wanker
Use git config --unset-all cocko.name to delete multiple keys that are the same.
Use git config --remove-section cocko to remove all cocko keys, including cocko.name & cocko.whatever
A file can be in one of a number of states
untracked Not being tracked at all by gitunmodifed. Tracked, but not changedmodified. Tracked, changed, but not marked for inclusion in next commitstaged Marked for inclusion in the next commitcommitted Saved to the repo historygit init to create a repo
git add <file> to add a file
git add . to add any new files
git branch to show current branch
git branch branch new_branch create a new branch, or create and switch in 1 command below:
git switch -c new_branch switches to a branch. -c creates it if it doesn't exist
git switch -c new_branch COMMITHASH create and swtich to a new branch that starts at commithash
git branch -m oldname newname rename branch
git branch -d old_branch delete an old branch. merges don't automatically delete old branches
To change the config to new repos are the same, such as master to main
git config --global init.defaultBranch main
git checkout has been superseeded by git swtich
The following two commands do the same. Preference is to use switch
git switch prime
git checkout prime
use git cat-file -p <hash> to view git objects
Simplist and most common. When the all the new commits are on the new branch, no merge commit is needed.
The pointer of the base branch is moved to the tip of the new branch
The active branch should be the one you want to merge other stuff info. ie, normally master
git branch master
git merge <other branch>
Primary use base for rebase is to do the following
Say you have the following branches
A - B - C main branch
\
D - E feature branch
Rebase let you take the divergent commits from one branch, eg feature branch, and move them to the tip of the base branch that the feature branch is based on.
A - B - C main branch
\
D - E feature branch
This then allows a fast forward merge and so therefore maintain a "free of merge commit" history which can be good for some reason
When doing a rebase, in the above example, you would have the feature branch as the active branch, then rebase to main
git branch feature_branch
git rebase main
An advantage of merge is that it preserves the true history. It shows when brances were merged and were. A disadvantage is that it can create a lot of merge commits, which make the history harder to read and understand.
Rebase gives a more linear history.
You can configur git to rebase by default on pull rather than merge to keep a linear history
to do this
git config --global pull.rebase true
You should never rebase a public branch (like main or master) onto anything else. Other developers have it checked out, and if you change its history, it will cause a lot of problems for them.
Doesn't matter for a private repo however.
git log shows a complete log
git --no-pager log -n 10 limit to 10 entries, and don't invoke the pager if it goes over a page
git log --oneline short log. only 1 line per entry (obviously)
git log --decorate=short (short=default, full | no are other options. how much info in branch name is shown.
git log --oneline --graph --decorate --parents show the parents hash as well.
To view contents or details of repository objects
git cat-file -p <commit hash>
To view a branch graph
git log --oneline --graph --all. --oneline is optional
To view a remote log
git log <remoterepo>/<branch>
git log origin/main
The commit hash is quite long eg 5ba786fcc93e8092831c01e71444b9baa2228a4f, but you can refer to any hash using only the first 7 characters
git reset --soft COMMITHASH
The soft option is useful if you want to go back to a previous commit, but keep your changes.
Committed changes will be uncommited and staged
Uncommited changes will remain staged or unstaged as before
git reset --hard COMMITHASH
Go back to the previous commit and discard all the changes
In git, another repo is called a remote. If you treat the remote as the "authoritative source of truth", (often github) you would name it as the "origin"
To add a remote
git remote add <name> <uri>
Often <name> would be origin. <uri> can be a url or a local path such as ../other/place
To show the remote origin
git remote get-url origin
Downloads copies of .git/objects from the remote repo into your current one.
Basically it downloads the metadata of the repo. Not all the files
git fetch
Get the actual files from the remote repo.
git pull pull current branch from remote repo
git pull <remote>/<branch>
Sends (pushes) local changes to any remote.
To push the local main branch to the remote origin's main branch
git push origin main
You can put a local branch to a remote with a different name by seperating names with a :
git push origin localbranch:remotebranch
You can delete a remote branch by pushing an empty branch to it
git put origin :<remote branch>
brew install gh
To setup and connect the gh cli to github
gh auth login
gh auth status to show the status of your github authorisation
git won't track any files in .gitignore.
You can have nested .gitignore files
If you put one in a subdirectory, it only applies to that directory and it's subdirectories.
| Pattern | Examples Matches | Explanation |
|---|---|---|
| **/logs | logs/debug.log logs/monday/foo/bar build/logs/debug.log | You can prepend a pattern with a double asterisk to match directories anywhere in the repository |
| **/logs/debug.log | logs/debug.log build/logs/debug.log but not logs/build/debug.log |
Match files based on their name and the name of their parent |
| *.log | debug.log foo.log .log logs/debug.log | An asterisk matches zero or more characters |
| *.log !logs/debug.log | debug.log but not logs/debug.log |
If a file matches a pattern, but also matches a negating pattern, it will not be ignored |
| /debug.log | debug.log but not logs/debug.log |
starting with a slash means only in the root |
| debug?.log | debug1.log but not debug10.log |
? matches only 1 character |
| debug[01] | debug0.log debug1.log but not debug2.log debug01.log |
square brackets match a single character from the set |
| debug[!01] | debug2.log but not debug0.log debug1.log |
|
| debug[a-z].log | debuga.log dedugb.log but not debug1.log |
|
| logs | logs logs/debug.log logs/latest/foo.bar build/logs | if you don't append a slash, the pattern will match both file and directory names |
| logs/ | logs/debug.log logs/anything build/logs/anything | appending a slash matches with directories (and includes all subdirectories |
| logs/ !logs/important.log |
logs/debug.log logs/important.log |
important.log ISN'T negated in this example. Due to a performance related quirk in Git, you can not negate a file that is ignored due to a pattern matching a directory |
| logs/**/debug.log | logs/debug.log logs/monday/debug.log logs/monday/pm/debug.log | double asterisk matches zero or more directories |
| logs/*day/debug.log | logs/monday/debug.log logs/tuesday/debug.log but not logs/latest/debug.log |
|
| foot[01].txt | match a file called foo[01].txt | use the backslash to escape the pattern matching characters |
stuff i've come across, but need to look into it some more as to what they do or when to use.
git ls-remote lists files on a remote repo