# List your configuration #git config --system settings.to.configure# Set the name# user.name can be your name, not only usernamegit config --global user.name "danielerat"#Set the emailgit config --global user.email davidodo2015@gmail.com#set the editorgit config --global core.editor "core --wait"# Configure the end of line in git:#!!!!!!Very important# If you are on windowsgit config --global core.autocrlf true# If you are on mac or linuxgit config --global core.autocrlf input# Set vscode as the default diff toolgit config --global diff.tool vscode# set how to run vs codegit config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOVE"
On windows, end of lines are marked with \r or \n where \r is Carriage Return and \n is Line feed, while in linux and mac os it is \n
Editing our configurations
Sometimes you want to configure the configuration to your needs, you would want to open the text file where they are written and manually edit them or simply type
#Open the configuration filegit config --global -e
#STAGGING INDEX(About to commit)git add file#REPOSITORY (Commited files)git commit file#Restore from staging to current working directorygit restore --stagged filename#WORKING (Current working dir)git restore filenamegit restore file.js # Copies file.js from index to working directorygit restore file1.js file2.js # Restores multiple files in working directorygit restore . # Discards all local changes (except untracked files)git clean -fd # Removes all untracked files
#git show hash# SHow all the changes introduced on this commitgit show d94f9f449c0b86a34ec02be780b360c07b7c20b# show the changes in a linear kind of stylegit show d94f9f449c0b86a34ec02be780b360c07b7c20b --color-wordsgit show 921a2ff # Shows the given commitgit show HEAD # Shows the last commitgit show HEAD~2 # Two steps before the last commitgit show HEAD:file.js # Shows the version of file.js stored in the last commit
#tag
sometimes we need to bookmark some point in our commits, like the commit that represent a given version , we use tags for this version .
# git tag v1.0 log_hashgit tag v1.0 5e72e21# we can represent the commit with a tag instead of the idgit checkout v1.0# List tagsgit tag# Creating an annotaged tag(name, email of tagger etc..)git tag -a v1.1 -m "My version 1.1"# get tag with messagegit tag -n# Check the annotated taggit show v1.1# Deleting a taggit tag -d v1.1
Branching allow us to diverge form main land of work and work on something else in isolation, a branch can be thought of a separate isolated workspace.
We work in an isolated space, make sure everything is working
The way git manages branches, it is very different from other version control system.
A branch is simply a pointer to a commit
The master branch is simply a pointer to a commit , as you make new commit git moves automatically to the new branch.
#git branch branchnamegit branch bugfix# check your branchesgit branch #output # bugfix # *mastergit status #output # On branch master # nothing to commit, working tree clean
To be able to work on your branch you have to move to it,
to change to your branch you use the switch command the checkout command used to work , but it had a lot of applications so switch is the new way
# Old waygit checkout branch# new waygit switch bugfix
Sometime when you are done working on a branch you need to delete it. and for that it is very simple you use the -d flag.
git branch -d bugfix/signup-form
When you want to delete a branch , and it happens to have commits they will tell you that it is not merged. you won't be able to delete it. great safety.
If you are really sure not to need a branch then you can simply use -D to delete the branch.
sometimes you want to see commits in the detached branch not in you master branch. you will use a command like this.
#commits that are coming in master# Commits in bugfixbranch not in master branchgit log master..bugfix/signup-form# list them on one linegit log master..bugfix/signup-form --oneline
Getting the actual changes and not the lists of commits §
You want to see the actual changes in a branch ? well yes you can do that too using diff.
git diff master..bugfix/signup-form# If you are already in the master branch, there is no need to specigy the master..git diff bugfix/signup-form# sometimes you wan to see the changes in terms of modified file.git diff --name-status bugfix/signup-form
You are back to a given branch and you would like to bright the stashed changes back to your working directory. but before you would wanna see the content of that stash
# git stash show sequence_numbergit stash show stash@{1}#orgit stash show 1
We Create a branch and we apply changes to that branch and we now want to merge the changes from that branch to our master branch.
In fast forward we will simply move the master pointer forward to the merge we desire.
You create you branch bring changes to your branch and after that you simply you do the same care to the master branch . you can not do fast ford otherwise you will loose the changes in the master from your branch.
You will do a 3ways marge to achieve the desired effect. §
You want to check whether you have a linear / non diverging merge
git log --oneline --all --graph#will show you the commits and you will be able to see whether a branch diverged or not.# If you have a linear path(no diversion) (then git will fast forward)
#git merge branchname# Make sure you are in the branch you want changes int(eg:master branch)# git switch mastergit merge bugfix/signup-form# git will do a fast forward merge.
You can can merge disabling the fast forward
git merge --no-ff bugfix/login-form# We are basically telling git that, hey even if the fast forward is possible we don't want it , create a merge comit that combines the cahnges in the branch and bring them to master.# usually a window open where you write your commit, but you can leave the default one too.#for a better visualiztiongit log --oneline --graph#* 951ee7a (HEAD -> master) Merge branch #'bugfix/login-form'#|\#| * e2ca4eb (bugfix/login-form) Update Toc.txt#|/#* 0cb2b37 (bugfix/signup-form) Fixing the bug that prevented the user from signing up#* a642e12 Add header to all pages.
You ca be working in a company that has a no fast forward policy you can simply disable the fast forward like this: git config ff no in your current settings/repo
In the real world, sometimes wen we merge changes, we get conflicts. they occur when
Same codes is changed on different branches in different places.
Changed in one branch and deleted in another
Same file is added twice in two different branches and the content are not the same.
You can manually merge the changes, which is simply by manually accessing the file and add remove or delete what is not needed then you save your change.
#abbort
Let’s say you want to merge and you get a hundred conflicts, what if you want to revert the merge and first deal with some stuffs and come back to the merge later ?
well yo can do that, you can undo the merge .
sometimes we do a merge and find out that our code does not compile or our application does not work.
that happens if we screw the merge.
In situations like this, we need to undo a merge and remerge.
First way is removing a commit/log
here you are rewriting history, and when doing so, you surely don’t want that if you shared your codes online already.
Reverting a commit approach, we will simply create a new commit that will cancel the changes.
When you made a bunch of nonsense commit, you might wanna remove the last commit.
git reset --hard HEAD~1# Roll back to the last 1 commit# When we use reset hard, we can still go back to that commit and be as in nothing happendgit reset --hard 5aae93 #PREVIOUS MERGE COMMIT
If you have shared you commits, eg: github with some people instead of resetting you can instead undo the changes to the state you wish. much more safer.
You create your branch and make a bunch of commit in there and you want to merge now, but here is a thing, you don’t want to merge with all these commits not to pollute your master branch what can you do ? squash merging it is a commit that combines commits from a given branch, all the changes for that , applied to master, it is not a merge, as for it does not have a parent
#git merge --squash branch_namegit merge --squash bugs# on this stage files are moves from that branch to your staging branch you have to commitgit commit -m "Squash mergins changes from the branch x"
When doing squash merge it is simper important to really remove that branch or it will create a real confusion in the future, cause if you use git branch --merged it will not show as merged yet you technically merged the change in the main
Because squash merge is technically not merged, deleting your branch has to be forced git branch -D bug.
Another technique for bringing changed into another branch is Rebasing
Rebasing Rewrites History, thus do not use it with codes you have shared.
#step1: Switch to our target branchgit switch bugs#step2: Execute the rebase commandgit rebase master# in the real world when rebasing you might find conflicts.#step3: Go back to master and mergegit switch master#step3: Mergins our branchgit merge bugs
You have a feature branch with two commits F1 and F2 one of these commits have some interesting changes we want to have in master, it is possible we can simply take that commit and put it in master.
#git will creat a folder with the repo namegit clone cloneUrl#clone and create your preffered folder namegit clone url folder_name
git log --oneline --all --graph# 282a917 (HEAD -> main, origin/main, origin/HEAD) Initial commit # origin/master: when cloning git names the source ripository origin. Origin/master tells us where the master is at on that repository.(where is the master in our remote directory(technically it is called a remote branch)) # origin/head: tells us where is the head pointer in our origin repository.
#fetch#pull
You want to download changes to your remote repository? well you can do that with the fetch command
# git fetch the_remote branch_name#git will asume that you want to fetch the maingit fetch#git will fetch all changes / commits of your origin branchgit fetch origin#git will download only changes from that specific branchgit fetch origin dev
When you fetch a repository, what happens is that it simply brings the commits but your head still points to the main. you are gonna have to manually merge.
We have pulled the changes and we want to know if we are being of how many commits
git branch --vv#output# main 282a917 [origin/main: behind 1] Initial commit
We have fetched our data, we know what we are behind for sure and we want to merge to be up to date with the origin.
#git merge remote_branch_namegit merge origin/main#verify that we are not behind.git branch -vv
pull=fetch + merge
To bring the changes from remote to local , most of the time we wan to do fetch followed by a merge. and we have a command for that pull
#will create a 3Ways mergegit pull# will Create a linear history.git pull --rebase
We are in our local repo and it is ahead of the origin/main we want to push our change to the remote repo.
# Send Commits to the origin (remote)# move the remote pointer to the new origin#move the origin/master to the pushed part#git push remote_repo branch_name# Git will asume that you want to push to the remote repo and the current branchgit push#push to the origin remote branchgit push origin#push the main branch to the origin.git push origin main
Now you want to work with branches and push them to github. well easy, you create them and push them (how do yo push them ? )
If you run git push while in your new branch, then you will get some error. saying that the branch you are trying to push is not linked to a branch in the origin.
# Get the branches and their remote trackinggit branch -vv# dev 89e7945 Changes to the developmet branch# * main 89e7945 [origin/main] Changes to the developmet branch# Check all the remote trancking branchesgit branch -r
If you want to push a branch for the first time you have to set the upstream branch (remote branch) with the -u flag.
#git push -u remote_name branch_namegit push -u origin dev
You are done with your branch and you would simply want to delete it from remote
#git push -d remote_name branch_namegit push -d origin Development
sometimes you have a remote tracking branch tracking changes of a given branch in the remote . you can remove automatically these branches using the prune command.
#listing all the remote branches.git branch -r# Delete the remote branch on github.git push -d origin feature/change-password# You have removed the branch from github, now you wanna remove it from your local repo, then remove the tracking origin branchgit remote prune origin
Quite often we would want our team members to help us reviewing our codes with a pull requests. with a pull request we essentially open a discussion with the team before merging to the main branch.
# Create a new branch add features and push it to github.git switch -C feature/login# make changes and stage the fileecho "Some changes on the feature/login branch" > text.txt# Add the change and commitgit commit -am "New file on the nea branch"#Push the branch.git push -u origin feature/login
We Use the git remote command to manage our remote repositories.
# Show the remote repositoriesgit remote# List move verbos info about the repogit remote -v#origin https://github.com/danielerat/Mars.git (fetch)#origin https://github.com/danielerat/Mars.git (push)
You would want to get updates of a particular repo you forked. what are the steps ?
# Scenario# step1 : You fork a project# step2 : you clone it to your computer from your fork# step3 : You get lazy, and the base gets updated(where you forked your codes)# step4 : You want the lates change cause you are crazy# Ste1: Create a remote branch (aka base branch)git remote add upstream# step2: Fetch the new changes from the remote branchgit fetch upstream#step3: merge to your main branchgit switch maingit merge base/master#step4: Push to your forked repo the latest changesgit push
#gitignore
If you don’t want to track a file you have to add them to your git ignore
Sometimes you create your git ignore after you have tracked some changes in a particular file , if you add that file to .gitignore later on, it won't still be tracked you need to remove the file to the cache
When you’ve already tracked files that you later add to your .gitignore file, Git might not automatically stop tracking those files. This is because Git’s tracking of files is based on their history. If a file has already been committed and is part of the history, adding it to .gitignore won’t immediately remove it from the repository.
Divide history in half and get to test and see where there is a problem in our codes
git bisect startgit bisect bad# Marks the current commit as a bad commitgit bisect good ca49180 # Marks the given commit as a good commitgit bisect reset # Terminates the bisect session
#git branch name_of_branchgit branch bugfix # Creates a new branch called bugfixgit checkout bugfix # Switches to the bugfix branchgit switch bugfix # Same as the abovegit switch -C bugfix # Creates and switchesgit checkout -b branch_name #same as above
The git stash command takes your uncommitted changes (both staged and unstaged ), saves them away for later use, and then reverts them from your working copy
#Stashinggit stash push -m “New tax rules” # Creates a new stashgit stash list # Lists all the stashesgit stash show stash@{1} # Shows the given stashgit stash show 1 # shortcut for stash@{1}git stash apply 1 # Applies the given stash to the working dirgit stash drop 1 # Deletes the given stashgit stash clear # Deletes all the stashes
#Output all commits made up on this filegit log --oneline filename#output all commits satatistic made on a file(+lines -lines and more.)git log --oneline --sat filename# See the actual changes of a given file per commitgit log --oneline --patch filename
The git reset command has three primary modes, each with distinct effects:
Soft Reset: This mode resets the HEAD pointer to a specific commit without modifying your working directory or staging area. It’s often used when you want to rewrite commit history before pushing changes to a remote repository.
Mixed Reset (Default): This mode resets the HEAD pointer and updates the staging area to match the specified commit. It leaves your working directory untouched, allowing you to review and modify your changes before committing them again.
Hard Reset: This mode resets the HEAD pointer, the staging area, and your working directory to match the specified commit. It discards all uncommitted changes, so use this mode cautiously.
Undoing Commits: You can use git reset to remove or modify commits. Soft reset is useful for rewriting commit messages, while mixed or hard reset can be used to remove commits from history.
Unstaging Changes: When you’ve staged changes but want to unstage them, use git reset with the mixed mode.
Starting Over: In cases where your working directory is in an undesirable state, a hard reset can revert everything to a specific commit.