-
Software Development is a continuous process
-
We are required to get snapshots of our software
-
Why do we use Git?
-
To follow development processes
-
To collaborate
-
Enabling us to split our project into particular branches
- Illustration of Working Directory, Staging Area, Local Repository, Remote Repository
- To see the properties of git configuration
git config --list- To set a name to configuration name
git config --global user.name "Muhammed Buyukkinaci"- To set an email to configuration email
git config --global user.email 'your_email_address@gmail.com'- To create a local repo
git init- To get information about files and changes
git status- To transfer all FILES to staging area
git add .- To add all modified files to git
git add -u- To transfer staged changes to The local repository
git commit -m "Transfering to the local repository"-
An VSCode extension named as Live Server can be used in HTML
-
To send all CHANGES to Staging Area
git add -A- After renaming a file, add all files to The Local Repository
git add .- To see short version of changes:
git status -s-
While committing, messages can be copies of the results of 'git status'
-
To roll back a change from Staging Area:
git restore --staged filename- To roll back a change from Working Directory
git restore filename- To see latest commit
# To see what happened in the last commit
git show HEAD
# To see in the HEAD-1 commit
git show HEAD^1
# To see what is committed in a hash
git show 7_DIGIT
# To see what happened in a tag
git show TAG_hERE- To see all commits in The Local Repository
git log- To see summary of commits
# A classical git log oneline
git log --oneline
# Detailed version
git log --oneline --decorate --graph
- To see only latest 2 commits
git log -p -2- To see commits after a time period
git log --since=10minutes- To go back to a specific commit
git checkout 7_DIGIT- To go forward to latest commit
git checkout master-
Checkout can be used to go back to previous versions.
-
To delete a commit and its effects
git revert 7_DIGIT- To revert a change of revert
git revert 7_DIGIT- While using
git reset, take care a lot. To remove staged files from Staging Area(Not Working Directory)
git reset FILE_NAME- To roll back from only The Local Repository
git reset --soft HASH_NUMBER- To roll back from Staging Area and The Local Repository
git reset --mixed HASH_NUMBER- To roll back from Working Directory, Staging Area and The Local Repository
git reset --hard HASH_NUMBER- Put the names of files that you don't want to be tracked into .gitignore file. A sample .gitignore file was listed below.
log.txt
directory/
*.py
- Create .gitignore firstly while creating a project. If you didn't do this, clear cache by command below.
git rm -r --cached .- To create a new branch
git branch branch_name1- To list all branches in a project
# To list all
git branch -a
# To list remote branches on client side
git branch -r
# To remove a tracked branch name
git branch -r -d REMOTE_BRANCH_TO_DELETE- To pass to a different branch
git checkout branch_name1- To pass back to master branch
git checkout master- While on master, merge different branches into master.
git merge branch_name1 branch_name2- To clone a Remote Repository to The Local Repository. While cloning, a default .git directory is created.
git clone REMOTE_REPO_URL
git clone REMOTE_REPO_URL new_folder_name
# shallow clone
git clone https://github.com/google-coral/tflite --depth 1- To show which files to be removed from working directory
git clean -n- To clean out which files to be removed from working directory
git clean -f- Rebase the current branch onto base. base can be a commit ID,branch name, a tag, or a relative reference to HEAD.
git rebase <base>- To add a new remote to local repo
git remote add origin https://github.com/user/repo.git- To fetch a specific branch from the remote. Leave off branch to fetch all remote refs. It allows only copying, not merging
git fetch <remote> <branch>- To fetch the specified remote’s copy of current branch and immediately merge it into the local copy. git pull = git fetch + git merge
git pull <remote>47)To push the branch to remote, along with necessary commits and objects. Creates named branch in the remote repo if it doesn’t exist.
git push
<remote> <branch>- To Reset staging area to match most recent commit, but leave the working directory unchanged.
git reset- Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory.
git reset --hard- Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory.
git reset <commit>- Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory.
git reset --hard <commit>- To Fetch the remote’s copy of current branch and rebases it into the local copy. Uses git rebase instead of merge to integrate the branches.
git pull --rebase <remote>
# Merge latest commands into your feature branch
git pull --rebase origin master- To Forces the git push even if it results in a non-fast-forward merge. Do not use the --force flag unless you’re absolutely sure you know what you’re doing.
git push <remote> --force- To push all of your local branches to the specified remote.
git push <remote> --all- Tags aren’t automatically pushed when you push a branch or use the --all flag. The --tags flag sends all of your local tags to the remote repo.
git push <remote> --tags- To Show difference between working directory and last commit.
git diff HEAD- To show difference between staged changes and last commit
git diff --cached- To delete a branch
git branch -d branch_name1-
To add a new developer to the existing project on GitHub, Settings --> Manage Access --> Invite a collaborator
-
github.com/octocat/Spoon-Knife project can be used while forking a project. After forking a project and making changes, we should create a pull request. Our pull request is going to be evaluated by project owner or team leader.
-
We can use GitHub to host our static websites. Make a repository named as GITHUB_USER_NAME.github.io .
-
To show which repos are available on remote
git remote -v- https://www.youtube.com/watch?v=SX8bHqXt8ws
- https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet
- How to git restore a particular extension
git checkout -- "*.xml"
- How to add a new remote repository to a local repository
#origin is the name of a remote repository in local computer.
git remote add my_awesome_new_remote_repo git@github.com:MuhammedBuyukkinaci/My-Git-Notes.git
git remote add origin git@github.com:MuhammedBuyukkinaci/My-Git-Notes.git- To remove a remote repository from a local repository
git remote remove NAME_OF_REMOTE_REPO_IN_LOCAL
# Example:
git remote remove origin
-
git-tower.com is a GUI to improve git facilities.
-
Git staging area is enabling us to make 2 different commits from a single file
import os # go to commit 1
import sys # go to commit 2-
Changes in a topic should belong to a single topic/issue.
-
git add -p index.htmlis chooging parts of a file to a commit, not a whole file. We are prompted to choose which parts to be committed thanks to-pflag. -
git commithas a subject and a body section. After putting changes to a staging area, typegit commitand a window is prompted. The first line is commit subject that shouldn't exceed 80 characters.The second line is empty. The third line is the detailed explanation
`
- 3 types of branches:
- Mainline branches like main or master, long living
- Integration branches like develop or staging, long living
- Feature branches (refactoring, experiment, bugfix, release etc.), short running
-
If you have staging, development, production environments, it is advised to mirror branches (main, develop etc.)
-
Commits shouldn't be directly merged/rebased to integration and mainline branches. They should be committed on feature branches.
-
Short lived branches are created for certain purposes like bugfix or refactoring or experiments or feature adding.
-
Githubflow is advocating a simple approach. 1 long running branch + feature branches(feature, bugfix, refactoring).
- Gitflow is a more structured approach.
- main: current production code
- develop: feature branches start from develop branches and merged back on develop branch
- feature: new attributes or bugfixes or refactoring are coded on feature branches.
- A tag named release should be added to release branches
-
Pull Request is a feature of git hosting platforms (github, bitbucket, gitlab)
-
Pull Request invites others(reviewers) to give feedback before merging changes in code.
-
Pull Request is enabling us to improve an open source project on a hosting platform like github. This happens in the following way:
Fork --> Change (Improve) the forked repo --> Open a pull request to original repo from new the repo on a new branch branch of forked repo to master branch of original repo
- Pull Requests are always based on branches not on individual commits.
-
git merge,git rebase,git pull,git cherry-pick,git stash apply, all of these may result to a merge conflict. -
Merging branches works effortlessly in most of the times because git is usually able to figure out what is going on.
-
Contradictory changes like
same line changed by 2 different branches, a file modified on 1 branch and deleted in other etc.may result in merge conflicts. -
You can't ignore merge conflict. You have to deal with before you can continue your work. Dealing with a merge conflict doesn't mean you have to resolve it; you can undo it and this is sometimes really helpful.
git merge --abort
git rebase --abort
- git is marking the promlematic ares via >>>>> or <<<<<<<. ====== is separating changes of different commits
-
The solution to merge conflicts is to clean up the file. GUI options like git-tower and Github Desktop are really helpful on solving merge conflicts. On the other hand, there are dedicated merge tools. For complicated conflicts,it is great to have dedicated merge tool at hand. A merge conflict tool can be configured via
git config. -
After dealing with merge conflict via GUI or manually or git merge tool, We have to commit this situation like any other ordinary change.
- The simple scenario for merge is a fast-forward merge.
- Normally, a commit is created by a human being. It is made after related changes. However, a merge commit is a little bit different. It isn't created by developers, it is created by git gui automatically. Its purpose is to connect two branches, just like a knot.
-
Rebase isn't better or worse than merge. Rebase makes the project history to look like a straight line without any sign that it had been split into multiple branches at some point.
-
An example usage of git rebase and what is going on behind the scenes are below.
git rebase branch_Name_to_integrate
-
Rebase rewrites commit history. <<<<<<< HEAD
-
Rebase should be used for cleaning up the local commit history. Don't use it on a remote repo.
-
Interactive Rebase allows us to manipulate commit history. Manipulate means change message, delete commit, reorder commits, combine multiple commits, edit on existing commis, split an existing commit into multiple commits. It is a swiss army knife which has several options together. However, it is a knife and be careful while using it.
-
Don't use interactive rebase on commits that were published on a remote repository. Interactive rebase should be used in cleaning up local commit history before mergings it into a shared team branch.
-
An example usage is below(commits are in reverse order, be careful):
git rebase -i HEAD~3
- If the latest commit was required to be changed, use
git commit --amend. For the other previous commits, use interactive rebase. Don't change of commit history of things that you already pushed into a remote repository. When *--amend * comment is used, it creates a new commit hash (7_DIGIT).
# To change commit message of latest commit
git commit --amend -m "new commit message"
- First enter
git rebase -i HEAD~3. It will prompt a new window asking that what kind of change (keyword) I want to make. Replace pick with reword. A new prompt will pop up. Rewrite commit message and see changes.
99.5) drop is the action keyword to delete the commit.
- Squash is combining 2 commits by creating a new commit
git rebase -i HEAD~4
# To combine 7_DIGIT_3 & 7_DIGIT_4, write squash before 7_DIGIT_3. It will merge 7_DIGIT_3 and its previous commit(7_DIGIT_4)
# pick 7_DIGIT_4 pick 7_DIGIT_4
# pick 7_DIGIT_3 ------> squash 7_DIGIT_3
# pick 7_DIGIT_2 ------> pick 7_DIGIT_2
# pick 7_DIGIT_1 pick 7_DIGIT_1
# To add a new file to a previous commit
git add filename
git commit --fixup 7_DIGIT_PREVIOUS_HASH
# fixup keyword combines the line above like squash
git rebase -i HEAD~4 --autosquash
# Split an existing command
100.5) Don't use interactive rebase for latest commit manipulation. Use it for more previous commands(HEAD~3 etc.).
-
cherry-pick allows us to pick individual commits to be integrated. It is on the level of commit, not on branches.
-
The main integration level should be branch level.
git mergeandgit rebasedo what we want in most cases. Cherry picking isn't a replacement of git merge and git rebase. -
Committing on a master branch directly is a practical use case for cherry picking. I n this case, it is necessary to move commit from master branch to feature branch.
-
A commit is made intp master wrongly. We want to move it into feature branch.
git checkout feature branch
git cherry-pick 7_DIGIT
git checkout master
# delete wrong commit from master
git reset --hard HEAD~1
git reset --hard 7_DIGIT
-
Reflog can be regarded as git's diary. It is a perfect choice if things go wrong.
-
For instance, we deleted 2 recent commits via
git reset --hardwrongly. However, we noticed this is a bad idea. Reflog comes in play in this situation. We wat to get back to the situation before 2 commits were deleted.
git reflog
git reset 7_DIGIT_ON_REFLOG
- To start a new branch from a particular commit
git branch NEW_BRANCH 7_DIGIT
- Reflog comes in handy when a branch is deleted wrongly.
git reflog
# find commit hash
git branch NEW_BRANCH 7_DIGIT
-
A submodule is a standard git repository. The ony speciality is that it is nested inside a parent repository.
-
Submodule property of git comes in handy especially if we want to include a 3rd party library or something like that. To use submodule of git, create a folder in the main repo and this is submodule.
mkdir lib
cd lib
git submodule add REMOTE_URL_OF_REPO
-
The actual content of submodule isn't stored in our parent repo.
-
After creating a submodule, a .gitmodule file is created in parent repo directly. It is also added to .git/config file.
-
git also stores a copy of submodules under .git/modules.
-
It is recommended to use Git GUI's like tower and Github Desktop if you are dealing with git submodules.
-
Git regards adding a submodule as a modification and that change ought to be committed.
-
When a repo is cloned from Github, it only has configurations of its submodules, not the content of its submodules. If you want to download submodule contents of repo, run the following after cloning.
git clone URL_OF_REPO
git submodule update --init --recursive
# or directly
git clone --recursive-submodules URL_OF_REPO
- Submodule repositories are always checked out on specific commits , not a branch. Content of a branch can change over time when near commits arrive. For submodule, we always want a specific version which was checked out.
- We can filter commit history by date, message, author, file, branch.
git log --after="2021-7-1" --before="2021-7-5"
git log --grep="refactor"
git log --author="Muhammed"
# Not to confuse filename with branch name
git log -- README.md
# To show commits in master and not in feature/login
git log feature/login..master
# To show commits in local master and not in remote master
git log origin/master..master
- grep can use regular expressions. Therefore, there is no limit to our creativity while filtering commits.
-
An tutorial for setting up ssh keys is SSH keys
-
-u flag in git push is used to set upstream. After setting the upstream via
git push -u origin master, we don't have to typegit push origin master.git pushis enough. -
To show differences between a master and feature branch
git checkout master
git diff FEATURE_BRANCH_NAME
-
It is recommended to create a PR (pull request) and let other developers review it rather than merging feature branch on top of master. After pull request is approved, pull changes via
git pull -
To create a branch and switch to that branch, there are 2 ways to do this:
# 1)
git branch feature_branch
git checkout feature_branch
# 2)
git checkout -b feature_branch
- stashing is a way to stash your changes somewhere and you can retrieve them later. It isn't making any commits. It is a temporary placeholder for changes.
git stashis useful especially if you don't want to lose your code and you want to switch between branches.
# Store changes in stashing
git stash
# Revert changes after switching between branches
git stash apply
-
HEAD is a pointer to last commit. HEAD is the currently active or checked out branch.
-
To unstage a file from staging area
git reset filename.py
- To undo latest commit
git reset HEAD~1
- To get rid of all of the changes after a certain point (C1-C2-C3-C4) (C4 is head and we want to move back to C2). HEAD is now pointing to HASH_ID.
git reset --hard HASH_ID_OF_C2
- To restore some chunks of a file which is staged(it will prompt up question about hwether to discard or not)
git restore -p filename
- To revert a commit which is in the middle (C1 - C2 - C3 - C4) (in this case it is C2), which means invalidating its effects
git revert HASH_OF_UNWANTED_COMMIT
- For
git reset, --hard and --mixed are most frequently used options. If you want to have a clean working directory, --hard is handy. --mixed is moving back a previous commit but it has undone changes in the working directory.
# Hard reset, cleans latest commits and latest commits disappear
git reset --hard 7_DIGIT
# To Roll back to one previous commit
git reset --hard HEAD~1
# Mixed reset, cleans latest commits latest commits appear in working directories as unstaged.
git reset --mixed 7_DIGIT
- To revert a file to a previous version in a previous commit
git restore --source 7_DIGIT filename
-
git switch BRANCH_NAMEis an alternative togit checkout BRANCH_NAMEin order to switch between branches. -
To rename a branch(while checked out the branch, which is HEAD)
git branch -m NEW_BRANCH_NAME
- To rename a branch which isn't checked out(non HEAD)
git branch -m PREVIOUS_BRANCH_NAME NEW_BRANCH_NAME
- Renaming a remote branch isn't possible. Instead, delete the former branch from remote and push the newly renamed branch to remote repo.
# Delete the old branch from remote
git push origin --delete OLD_BRANCH_NAME
git push -u origin NEW_BRANCH_NAME
- Tracking connection is used to be able to use
git pullorgit pushdirectly. To establish a tracking connection
git branch --track LOCAL_BRANCH_NAME REMOTE_BRANCH_NAME
# or
git checkout --track REMOTE_BRANCH_NAME
-
Tracking connection is useful in whether to notice remote and local branches diverge or not.
-
To delete a branch from remote
git push origin --delete BRANCH_BAME_TO_DELETE_ON_REMOTE
-
Git may not recognizes changes in file names. For instance, if we renamed a file from File01.py to file01.py, git may not detect the change in uppercase/lowercase. In this case, changing it to file_01.py is going to be detected.
-
In order to prevent git commands from behaving like less or cat commands, no pager can be useful.
# git branch
git config --global pager.branch false
# git log
git config --global pager.log false- To change editor option to vim instead of nano in git
git config --global core.editor "vim"-
Let's assume we are working on a feature branch based on master and remote master has changed. We should always make
git pulloperation and resolve merge conflicts before pushing into remote. -
Git log 2 dots .. and 3 dots difference
- Git diff 2 dots .. and 3 dots difference
- Git tag is a pointer to a particular commit. It is permanent. They shouldn't be modified. There are 2 types of git tag. Lightweight and Heavyweight. It is used in releases. Lightweight tag is preferrable. Heavyweight tag is containing both tag message and commit message.
## Lightweight Tag
# To assign a tag to current commit
git tag TAG_TO_ASSIGN
# To assign a tag to a previous commit
git tag TAG_TO_ASSIGN 7_DIGIT
## Heavyweight Tag
git tag TAG_TO_ASSIGN 7_DIGIT -m "message"
-
git checkout --orphan BRANCH_NAME_HEREis a way to clean up the commit history in BRANCH_NAME_HERE. We are using it for documentation pages or switching to public/private repos etc. We can use it to hide the previous history of an open source project. It can be used viagit checkout 7_DIGIT --orphan BRANCH_NAME_HEREto start from an existing commit. -
git grep WORD_TO_SEARCHcan be used to search a word in committed files.














