Command line tutorial
File compare tool from OS
Windows :- FC (File compare)
Linux/Mac :- Diff (Difference)
Check git version
Git commit story
- Each commit has an Id. For a medium sized repository, first 8 chars can be enough to uniquely identify the commit.
- Details log command,
git log --stat
- Display the difference between two commits,
git diff COMMIT_ID_1 COMMIT_ID_2
First write source commit and then destination commit. Depending on the source and destination order, you will be displayed add/delete codes.
Altering these two will show the same changes but in opposite order.
- There is a difference between copy and clone. In Clone, history will be downloaded as well as content.
- Activate colorful git bash:
git config --global color.ui.auto
git checkout COMMIT_ID (Checkout a commit)
git checkout BRANCH_NAME (Checkout a branch)
Whenever you checkout a previous commit, you will be in detached HEAD state. However you can restore the head by
git checkout master (Go back to master)
git checkout BRANCH_NAME (Go back to a branch)
Essentially it means, you are looking at a commit that was not labeled with a branch name.
You can see where HEAD is points to by command,
git log works from current branch to the parent commit
if you checkout an earlier commit and make changes and create a new commit then the new commit is lost and will not be displayed in output, cause it’s not reachable from current branch.
You can create a branch though to retain the changes in that newly created commit,
git checkout -b new_branch_name
Download two files
add these two files in your .bash_profile like this,
Set default editor to write commit messages
If you would like to open up your favorite editor whenever you write,
git commit then run the following command,
git config --global core.editor "SUBLIME_PATH -n -w"
Here we are assuming your favorite editor is Sublime and replace
SUBLIME_PATH with Sublime executable file.
In general if you would like to create an alias, (i.e typing a shortcut to open up Sublime or any other editor) the follow the command in your .bash_profile file
alias subl = "SUBLIME_PATH"
Common git commands
There are 3 spaces:
- Working directory
- Staging area
Create a file,
echo "First change" > index.txt
Initialize a repo by,
index.txt is in your working directory.
git add index.txt you can add this file to staging.
git add . will all files to staging.
When you commit, git takes the entire changes of staging area and make a commit to repo.
Commit message style
feat: a new feature
fix: a bug fix
docs: changes to documentation
style: formatting, missing semi colons, etc; no code change
refactor: refactoring production code
test: adding tests, refactoring test; no production code change
chore: updating build tasks, package manager configs, etc; no production code change
Subjects should be no greater than 50 characters, should begin with a capital letter and do not end with a period.
Use an imperative tone to describe what a commit does, rather than what it did. For example, use change; not changed or changes.
Not all commits are complex enough to warrant a body, therefore it is optional and only used when a commit requires a bit of explanation and context. Use the body to explain the what and why of a commit, not the how.
When writing a body, the blank line between the title and the body is required and you should limit the length of each line to no more than 72 characters.
The footer is optional and is used to reference issue tracker IDs.
Example commit msg
feat: Summarize changes in around 50 characters or less More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of the commit and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); various tools like `log`, `shortlog` and `rebase` can get confused if you run the two together. Explain the problem that this commit is solving. Focus on why you are making this change as opposed to how (the code explains that). Are there side effects or other unintuitive consequenses of this change? Here's the place to explain them. Further paragraphs come after blank lines. - Bullet points are okay, too - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here If you use an issue tracker, put references to them at the bottom, like this: Resolves: #123 See also: #456, #789
Commonly used git situations
- You can compare two commits by git diff, but there is no Id in staging and working directory. So to compare working directory with staging area use no-arg git diff like this,
- To compare staging with repo
- Discard changes in working directory
- To discard any changes in working and staging area (be very careful, you can not revert this, codes in working and staging area have not been recorded )
- To go back to a particular commit, by discarding all the commits after it
- To go back to a commit but keeping your working directory as it is you can use reset soft. It will make code to move to that commit but your working directory will be same as of now. So the newly made changes will be there but code is commited upto that desired commit.
- To delete changes from staging area/li>
git rm --cached FILE_NAME
git diff --staged
git checkout -- FILENAME
git reset --hard
git reset --hard DESIRED_COMMIT_ID
git reset --soft DESIRED_COMMIT_ID
- Display all branches as a list
- Create a branch
- Checkout a branch
- Graphical view of branches
- Graphical view of branches (shorter)
- Delete a branch
- Display the recent commit of all branches
git branch BRANCH_NAME
git checkout BRANCH_NAME
git log --graph master BRANCH_NAME
git log --graph --oneline master BRANCH_NAME
git branch -d BRANCH_NAME
git branch -v
How git merge works!
Suppose original file content is like below,
Now Tarif vai made some changes
Tarun vai also made some changes
Now if you ask git to merge the changes how will it manage to merge?
We are certain that,
will present in final merged version, as these both are common in all 3 versions.
A will not present. Becasue, Tarif vai deliberately removed it and Tarun vai didn’t do anything. Of course you don’t want to see a line in final merged version that has been deleted explicitely.
C will be present as Tarun vai added it.
E will be present as Tarif vai added it
When you merge two branches, git essentially creates another commit, called merge commit. But you may have missed it before because of IDE or SCM GUI.
Suppose, your master branch has some new commits and you are merging a previously created branch with it. Now if you run
git log, in what order the log file will be displayed?
– It will be displayed in chronological order. That means, commits log will be jumbled up as the commits have been created in different point of time.
How will it affect you?
– If you run
git diff of two consecutive commits, you may experience a large number of changes. May be because they are from differnt branch and just happen to reside together because of their commit time.
How do you get the REAL changes of a commit is this situation?
git show COMMIT_ID, this will display the diff of this commit to it’s immediate parent commit
Merge conflict ocurres when two persons make changes in a single line. For example,
Original file content was,
Tarif vai made changes in 2nd line,
Tarun vai also made this his changes in 2nd line,
Before proceed with Git, you need to resolve the conflict. Remember, merge and conflict resolution goes into a single commit.
Rebase is kind of an extension of merge. You still have to do the merging but the end result will be a bit differnt. Follow the concepts,
- From a feature branch, if you rebase to master,
git rebase masterthen the unique commits in feature branch will be applied to one by one on the top of present day master branch.
- After the rebase you still need to do the merging. Checkout master branch and run,
- Now if you try
git log --oneline --graph, you should see a cleaner commit history, as if there was no branching and you just applied the changes in master directly.
git merge FEATURE_BRANCH
We learnd there are 3 spaces in local repository: Working, Staging and Repo.
In remote repository like Github there are two types of repository: Origin, Upstream (You can create more if you wish, but these two are most common)
- You can add multiple remote repos, if there is only one repo then we usually refer it by name origin
- Fetch and Pull could be different url. To check remote urls,
- To push to origin follow the format git push TARGET_REPOSITORY LOCAL_REPOSITORY
git remote -v
git push origin master
Fork is a concept introduced by Github, it’s not part of Git. Gitlab might call it a different name.
Fork means to clone repository from a other’s github account to your github account
When you push to remote branch there are two branches in your local machine,
What happens when you have changes in both local master and origin master?
– Let me introduce git fetch. Git fetch updates your local machine’s origin/master and does not touch your local master branch. So there is no chance of conflict. After that you can use git log and git diff to compare.
Now you can also merge manually or you can do the fetch and merge combined by this command
git pull origin master
For log and diff in origin/master follow the command,
git log origin/master
git diff origin/master master
You can update all yoru local copies of every branches in the origin repositry by,
git fetch origin
If git pull == git fetch + git merge, then why git pull doesn’t generate a new merge commit like we see before?
– It’s called fast-forward merges. When base commit is ancestor of the other commit then it happens and merge commit will be a redundant commit, don’t ou think?
When creating pull request from github, make sure you are selecting correct parent and correct child and also make sure chind branch can be successfully merged with parent branch so that one can accept just by a single click. Otherwise github will disable the merge request button.
So whenever you are making a pull request you need to pull the parent branche’s latest code and resolve all conflicts and create the pull request. If you request gets rejected then,
- fix the issue
- pull again from parent branch (if there is some changes meanwhile
- resolve conflicts (if any)
- push again
if you would like to get updates from Grand parent repo (from which you made the fork) or would like to make a pull request to Grand parent repo then you need to add the Grand parent repo as upstream by convention. it will create an upstream/master in your local machine.
To add an upstream url,
git remote add upstream GIT_URL
Now the rest follows exactly same as origin, just make sure to use upstream/master instead of origin/master when you refer to upstream.
Thanks for reading!