# Git cheatsheet - Made by [vanyadarkov](@https://github.com/vanyadarkov) - From [leelawebdev course](https://www.youtube.com/playlist?list=PL_euSNU_eLbegnt7aR8I1gXfLhKZbxnYX) - https://www.atlassian.com/git - https://git-scm.com/doc - https://git-school.github.io/visualizing-git/ - for visualizing git operations ### [Commands] - ```git help``` = common commands - ```git help -a``` = list of all commandds - ```git help <command>``` - get help on a command ```<command>``` ### [Init] - ```git init``` - create a new local git repository ### [Configuration] - git config - ```git config --list --local/--global/--system``` - ```git config for help``` ### [Add/Remove/Move] - ```git add <file>``` - add file to staging area - ```git mv <file>``` - mv file - ```git rm <file>``` - remove file - ```git rm --cached <file>``` - remove from stage area (files that are set to be committed) ### [Restore] - ```git restore <file>``` - discard changes in file ```<file>``` and get previous version - ```git restore --staged <file>``` - restore from staging ### [Commit] - ```git commit -m "<message>"``` - ```git commit --amend``` - for commiting small changes into the last commit (only for changes on local repo) ### [Status] - ```git status``` - see the repository status on the current branch - ```git log --graph --abbrev-commit --decorate --date=relative --all``` - see pretty printed repository log ### [Track changes] - ```git diff``` - ```git diff --staged``` - ```git diff HEAD``` ### [Branching] - ```git checkout [-b] <branch_name>``` - switch to branch ```<branch_name>``` [```-b``` creates branch if doesnt exists] - ```git branch <branch_name>``` - create new branch - ```git branch -d <branch_name>``` - delete ```<branch_name>``` - ```git branch -m <old_branch> <new_branch>``` - rename ```<old_branch>``` to ```<new_branch>``` ### [Merging] When developping a new feature, it is recommended to do it on other branch than main. If we want the two branch two merge, we use merging - ```git merge <source>``` - merge current branch with ```<source>``` branch - if conflicts, resolve them and then commit - ```git merge --abort``` - abort merging ### [Rebase] - Rebasing is often used as an alternative to merging. Rebasing a branch updates one branch with another by applying the commits of one branch on top of another branch - Git rebase is used to clean up our local commit history. - Rebase is a advanced command which is used rarely. - Merge preserve history - Rebase doesn't preserve history |When do not use Rebase|When to use rebase| |--|--| |The branch is public when it is shared to all the developers|Cleaning up your commits before sharing your branch (e.g. before merging a branch with a lot of commits, rebase it to decrease the number of commits and then push)| |Most of the teams prefer merge over rebase|Pulling changes from another branch without merge| - ```git rebase <branch>``` ### [Cherry pick] - Cherry pick is used if you want to apply particular commit from one branch into another branch - Cherry pick is mainly used if you dont want to merge the whole branch and you want some of the commits. - Cherry pick just like rebase it is an advanced concept and also a powerful command - Cherry pick is useful tool, but always it is not a good option - It can cause duplicate commits. - Mainly cherry pick is used for the bug fixed where you want to place that bugfix commit in all the version branches - It is also used when we accidentally made a commit in wrong branch - ```git cherry-pick <commit_hash>``` ### [GIT Reset] - reset stands for undoing changes - does different things in different contexts - reset is used to move the branch from one commit to another commit - the above commands only move the HEAD pointer (commit, checkout, merge, rebase) - reset has options - ```--hard``` -> moves the files both to working area and staging area - ```--mixed``` -> moves the files only to the stage area (default) - ```--soft``` -> doesnt move the files - ```git reset <commit>``` - reset changes to the ```<commit>``` stage ### [GIT Stashing] - ```git stash``` - save the changes that are not staged for commit to stash - ```git stash save <name>``` - stash and save it as ```<name>``` - ```git stash list``` - check the list of stashes - ```git stash pop```- pop the recently pushed stash into the branch - ```git stash apply <stash_id>``` - apply the changes to the current branch - ```git stash show <stash_id> [-p]``` - see the details about the stash [-p for changes] - ```git stash drop <stash_id>``` - delete the stash item - ```git stash clear``` - clear the stash list - ```git stash branch <branch_name>``` - creates new branch with stashed data ### [GIT Checkout] Besides creating or switching to another branch, git checkout can move the head to a particular commit. Switching to other commit will put us in detached head state - ```git checkout <commit_hash>``` - ```git checkout HEAD~<N>``` - go to N commits before the ```HEAD``` - ```git checkout HEAD <filename>``` - discard the changes from ```<filename>``` ### [GIT Switch] - ```git switch <branch_name>``` - switch to so another branch - ```git switch -c <new_branch>``` - switch to new branch ### [Setup SSH key] - ```ssh-keygen -t ed25519 -C "ur_github@email"``` - ```eval "$(ssh-agent -s)"``` - ```ssh-add ~/.ssh/id_ed25519``` - add ssh public key in the github account - ```ssh -T git@github.com``` - log from local with ssh to git - remote link to repo has to be ssh in order to commit without credentials ## [Working with remote] ### [Git remote] Remote is the repository hosted on a server (such as Github). Often, remote is always refferenced as origin, which is nothing but a shortcut to repo url. - ```git remote add origin <url>``` - add remote url as origin - ```git remote -v``` - check remotes (push and fetch[getting from repo]) - ```git remote rename <old_name> <new_name>``` - ```git remote remove <remote_name>``` ### [Git push] - ```git push <remote_name> <branch>``` - push to remote_name working tree from branch. - ```git push <remote_name> <local_branch>:<remote_branch>``` - push to remote from ```local_branch``` to ```remote_branch``` - **!!! Not a common action !!!** - ```git push -u origin master```- ```-u``` option sets the upstream for local master to track up on remote branch master from origin. The next git push without any options on master branch will push to origin/master ### [Git remote branches] - ```git remote -r``` - see list of the remote branches - ```git clone <url>``` - will clone only the default remote branch - ```git switch <remote-branch>``` - switch and set the upstream between local and origin branch (if no branch with same name on local exists) ## [Git fetch and pull] ### [Fetching] - allows to download changes from remote repo - those changes will not be atuomatically integrated to our working files - just lets to see what others have been working in, without merging those changes into your local repo - in other words, go and get the latest info from remote, but dont add it into my working dir - ```git fetch <remote>``` - fetches all the branches and history from a specific remote repository. it only updates the remote tracking branches - ```git fetch origin``` - would fetch all changes from the origin remote repo - default remote is origin - ```git fetch <remote> <branch>``` - fetch specific branch from remote - ```git fetch origin master``` - retrieve latest info from master branch on the origin remote repo - after fetching, i will have those changes on the machine - if you want to see then you have to do the checkout to origin/master - local master will stay untouched ### [Pulling] - similar to fetch - command you can use to retrieve changes from the remote - pull will actually updates our head branch with whatever changes are retrieved from the remote - other words: go and download data from remote and update my local repo with those changes - ```git pull``` = git fetch + git merge - **!!!** ```git pull <remote> <branch>``` - really matters where we doing git pull. git pull will fetch the changes from remote on branch ```<branch>``` and will merge those changes in current branch on local - because pull using merge, it can result in merge conflicts - if we dont specify nothing to git pull, it will asume - origin - default remote - branch will default to whatever tracking connection is configured for the current branch - **not recommended to pull if you have uncommitted changes!** ### [GIT Forking] - forking strategy or workflow is nothing but the contribution, because actual code owners/developers cannot add every contributor as contributor/collaborator in Github repo - forking enables anybody to try and make a contribution for the repository - no permissions needed - making changes in fork then - PR - anybody can make PRs - forking means - "make me my own copy of this repo" - forking is not git native - to keep local repo in track with origina one, add remote to the original (with other name than origin) - ```git remote add <name> <link_to_original>``` - ```git fetch <name>``` - to update ### [Pull requests] - Pull requests is a feature that represents a query to other collaborators to add our changes from a feature branch to the main branch. Is not a git native feature, it is done on git hosting services (GitHub, GitLab, Bitbucket etc.). - Pull request is nothing but - hey, i've done my work on my branch. Can you merge my code into the main branch? - It is not recommended to push directly to the main, in many cases main/master branch has branch protection rules. - Pull request may result in merge conflicts, so somebody has to resolve them (contributors or by the one who approves the PR) - Pull request, because it uses merging, will result in a new commit, so after the PR is done, be sure to update your branch (by merge/rebase) ### [GIT Tagging] - tags are pointers that refer to a particular points in git history. we can mark a particular moment in time with a tag - tags are most often used to mark version releases in projects (v4.1.0, v4.1.1 etc) - think of tags as branch referenes that do not change. once a tag is created, it always refers to the same commit. it's just a label for a commit Two types of tags - lighweight tags - lightweght tags are light weight. they are just a name/label that points to a partcular commit. is much like a branch that doesn't change - it's just a pointer to a commit. - ```git tag <tag_name>``` - create a tag with name <tag_name> on the current head - annotated tags - store extrameta data including the author's name and email, the date and a tagging message (like a commit message) - annotated tags, however are stored as full objects in the git database - it's generally recommended that you create annotated tags so you have full information. - ```git tag -a <tag_name>``` - ```git tag``` - will print a list of all tags in the current repository - ```git tag -l <pattern>``` - search for tags that match particular pattern - ```git checkout <tag>``` - checkout to a particular tag **(DETACHED STATE)** - tags are not defaultly pushed to the remote. - ```git push origin <tag_name>``` - push the tag ```<tag_name>``` to the origin - ```git push origin --tags``` - push all the tags to the remote origin ### [Semantic versioning for a software] Semantic versioning specs outlines a standardized versioning sytem for software releases. It provides a consistent way for developers to give meaning to their software releases. Version consists of three numbers separated by periods. - 4.2.1 => Major.Minor.Patch - Patch release (1.0.1) - patch releases normally do not contain new features or significant changes. They typically signify bug fixes and other changes that do not impact how the code is used. - Minor release (1.1.0) - minor releases signify that new features or functionality have been added, but the project is still backwards compatible. - No breaking change. The new functionality is optional and should not force users to rewrite their own code. - Major release (2.0.0) - major releases signify significant changes that is no longer backwards compatible. Features may be removed or changed substantially. ### [Git reflogs] The term reflogs is a short form for Reference logs. Just logs that git keeps for us as a record. Git keeps a record of when th tips of branches and other references were updated in the repo. - ```git reflog``` - view and update these reflogs Git keeps reflogs on your local activity only. They are not shared with collaborators. Reflogs also expire. Git cleans out old entries after 90 days, but can be configured. Accepts also subcommands like: - ```show, expire, delete, exists``` - ```show``` is the only command used variant and is default one. - ```git reflog show <branch>``` - logs for the tip of the ```<branch>``` - ```git reflog show HEAD@{N}``` - reflogs from ```HEAD@{N}``` - ```git reflog show HEAD~3``` - 3 reflogs above current - ```git reflog show master@{1.day.ago}``` ### [Git aliases] - ```git config --global alias.<alias> <command>``` - or in ```.gitconfig``` ``` example [alias] s = status cm = commit -m ``` - so when using ```git s``` it will act the same as ```git status```