Skip to content

Instantly share code, notes, and snippets.

@gauravgrover95
Last active August 24, 2018 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gauravgrover95/fc3141db5f14cb0f6451b787b7fbba9f to your computer and use it in GitHub Desktop.
Save gauravgrover95/fc3141db5f14cb0f6451b787b7fbba9f to your computer and use it in GitHub Desktop.
Git Commands

Branching

  • Branching is where things start to get little complex for beginners.
  • It happens because our mind has always been trained to think logic in a linear fashion and so is how we think in software development process.
  • Before going on we should keep following things in mind.
    • Branches are awesome.
    • Branching allows us to play with the software while preserving the serious developments of software.
    • Branches lets us collaborate with others. Everybody using our software can modify or fix bugs in our software to make it better and send back the changes for us to merge in the main software.
    • Branching allows us to test for new feature addition and check if it doesn't break down the original code.
    • Branching allows to create seperate flow of commits for everyone so that their work once pushed to the remote central repo, doesn't disturb the stable flow of commits and can be reviewed before final integration.
    • last commit is said to be parent for the new commit. and the new commit point to its parent commit. View it here.
    • Branches are merely pointers to a commit and can grow on seperately of the main development flow.image.
    • two branches can point to same commit at a time. image
    • A tag is similar to branch but one tag can point to a just single commit and remain pointing to that commit even when newer commits are made. Donot worry we will see it along other branch names in the history of branches section
    • branch name cannot have spaces or double dots(..) in between their names.

you may be working on a new feature but realize that a critical error in your application needs to be fixed immediately. You can quickly create a new branch based off the version used by customers, fix the error, and switch back to the branch to which you’d been committing the new feature.

Viewing all and current branch.

  • Viewing local branches
  • Current branch is the branch in front of asterisk(*) sign and colored.

git branch

  • Viewing remote branches

git branch -r

  • Viewing all branches(local and remote)

git branch -a

Creating a new branch

  • creating branch without checking out there

git branch <branch_name>

  • creating branch with checking out there

git checkout -b <branch_name>

  • creating branch by defining its <start-point>.

git branch <branch_name> <start-point>

-Examples

git branch abc master~3

git branch abd b35d1c5

git branch BugFix-2132

Checking Out

  • Checking out refers to moving on some node/commit in histroy, whether its on same or different branch.
  • If we simply use branch name that will take us to latest commit in that branch.
  • We have to use SHA-1 hash of the commit or we can use simply references.

git checkout <address/commit/branch_name>

=> btw branch name is also a referrence. Example:

=> git checkout master~3

Deleting branches

  • Deleting from remote:

git push --delete <branch_name>

  • Deleting from local:

git branch -d <branch_name>

Renaming/Moving branch

git branch -m <new_name>

Viewing Branch hsitory

  • Viewing a single branch history is same as viewing history normally using git log commands.

git log --decorate --oneline

git log --graph --decorate

  • But what takes little efforts is to learn how to view history of all branches together or to view differences between two of them.

  • Full difference with relative commit times and branching.

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative master..branch-X

  • If above is a bit complicated then we can do alias in unix like systems.

alias diff-branches="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative". Then do this diff-branches master..branch-X. Now it's not complicated

  • Basic difference between logs of two branches.
  • We use 3 arguments to make it comfortable to read --oneline, --graph & --decorate.
  • We can use them seperately or merge them together in combinations
  • only downfall of using this is the time visualization. that will be missing in comparision to above.

git log master..sandbox

git log --oneline --graph --decorate master..sandbox

  • Visualizing all log with branching in terminal.

git log --oneline --graph --all --decorate

-> usually I prefer single line commits even for all with just branch's end information. git log --all --decorate does that job for me.

  • We can even limit the latest number of commits to be shown by just passing a numeral argument.

git log --oneline -5 master..refactor

Merging

  • Merging is the process of importing commits/changes from other branch to the current branch.
  • Usually every commit has one pointer to its parent commit. But if the merge commit is formed, it has 2 parent pointers to 2 branches(1. branch that is getting import, 2. branch that into which import is done.)
  • Sometimes we see a message fast_forward_merge while performing merge. It means that seperate merge commit was made. Simply commits from the branch getting imported is added on top of the branch to which the import is being done.

git merge <branch_to_import>

Handling Conflicts

  • Before Handling conflicts, it is important to understand when does a conflict occur.
    • Conflict does not occur when we add spaces in between code.
    • Conflicts does not occur if we add more code to same lines.
    • Conflict does not occur if we had new lines between code.
    • Conflict does occur when in two seperate branches we edit the same line of code not neccessarily on same line number. That means:
      • Adding different code words.
      • Deleting different code words.
      • Addition and deletion of words in same line.

For Example following mentioned code in same example are in two different branches but in same file and same position relative to other code.

Ex1: echo "Hello there"; && echo "Hello there. My name is Gaurav"; does not produce conflicts.

BUT

Ex2: echo "Hello there"; && echo "Hello Buddy!"; does produce conflicts.

  • There are two way of handling conflicts.
    1. Manual Handling.
    2. Using mergetool
  • It is difficult to explain conflicts in plane text. Below videos does wonderful jobs for the same.

Youtube - Jeff-Shantz: Manual Handling

Youtube - Apple Juice: Merge Tools

Tags

  • As discussed previously, tags are just the constant pointers to a specific commit.
  • Think of tags same as we think of milestones in any journey.
  • We can define the milestones in the journey of software development.
  • Usually people tag a particular commit as the software versions. See Semanitc software versioning here
  • Adding tag:

git tag 0.0.1

  • View Tag list on a branch

git tag git tag -n --> displays tag with first line of commit

  • checking out to a tag.

git checkout 0.0.1

Some Good Reads:

Create New branch from old commit

git checkout -b justin <SHA-1 of old commit>

OR

git branch justin a9c146a09505837ec03b

Getting Remote Pull request into local repo

git checkout -b saskaale-master master

git pull https://github.com/saskaale/ccNetViz.git master

Git pretty log

git log --graph --pretty="format:%C(yellow)%h%C(cyan)%d%Creset %s => %C(green)%an%C(white), %C(red)%ar%Creset"

Deleting a git alias

git config --global --unset alias.<name-of-alias>

To be added

Git Config

  • Basic Configurations

git config --global user.name "gauravgrover95"

git config --global user.email "gauravgrover95@gmail.com"

  • Viewing git configurations

    • listing specific configurations

    git config user.name OR git config user.email

    • listing all configurations

    git config --list

Commiting changes

  • Initializing git repository with a specific name. Otherwise it takes up the name of the folder we are initializing it.

git init RepoName

  • adding files to staging area
    • We can also Enable Tracking of a file without adding its content code to staging area using -N flag

git add . // adding every change to staging area in current repository

git add --all

git add -A // adding all the changes including file system changes (new file/ delete file/ move file)

git add <file>

git add <file1> <file2> ...

git add -N <file_name> OR git add -N <path/to/file>

  • committing changes with message

    • Simple commit: message should not extend 50 characters.
    • First line is the subject of the commmit. next lines act as body of commit like email

    git commit -m "Initial commit"

    • Using commit commad without any flag/options will open text editor of your choice to write your commit.
    • To change preference of text editor goto

    git commit

    git config --global core.editor "vim"

Viewing History

Basics

  • simply using the log satement gives full detailed commit history with author name,mail and date of commit
  • pretty log is also available which shows just commit message in one line(subject). This fill show full SHA-1 and commit in oneline. --pretty=oneline
  • We can also abbreviate SHA to just 7 characters which is what we need when we need to refer commit uniquely as their reference. by passing --abbrev-commit.
  • In fact what devs usually prefer to do is just pass a single argument --oneline is short for --pretty=oneline --abbrev-commit
  • We can also use pretty colors to view name of branch(yet to be covered) we are on, in git log using --decorate argument. Order of the arguments doesn't matter.

git log

git log --pretty=oneline

git log --abbrev-commit

git log --oneline

git log --decorate or git log --decorate --oneline

Aliasing

  • To be honest I feel even the oneline argument pretty long to write.So I prefer to make it even shorter using git alias

git config --global alias.lg "log --oneline"

git lg

  • For detailed analysis of history of current and the branches merged into it (also, master branch if itself it is not).

git config --global alias.lgd "log --oneline --graph"

git lgd

Extras

  • git log can also be used with --patch or -p command to show diff between commits.
  • There are two more formats in which we can see diff in log itself i.e. --stat or --word-diff
  • For large commits, better will be to use --stat to show diffstat between commits.
  • --word-diff uses same format as the basic diff i.e. unified diff format but it shows diff per word rather than showing it per line
  • one situation where word-diff becomes really helpful is when we compare text files rather than code files where we have paragraphs

git log --patch

git log --stat

git log --word-diff

Differentiate between commits

  • diff is a basically a unix command that was used to view changes or delta between contents of two directories or folders. The format in which it shows the difference is called unified format diff

  • Same mechanism is used in git with same diff command.

  • differences are always relative. while comparing two commits, with respect to one commit, comparing other we can say that some lines are added but if we see the same difference with respect to other branch we will say same lines are deleted.

  • In git diff command we calculate difference with respect to the first argument we pass. By default second argument is current working directory.

  • git diff without any arguments shows differences with respect to last commit in the current working directory.

git diff

  • git diff without any arguments with --cached option will show differences with respect to last commit in the staged files.

git diff --cached

  • git diff master shows differences with respect to last commit in the current working directory. same as git diff

git diff master

  • If you create a new file that is not automatically tracked until you add it to staging area. But there is alternative to track for changes the file without adding it to staging area. git add -N newfile.txt

  • view diffferences between current commit and the previous commit..

git diff master~1 master

  • viewing difference between current and previous commit for specific file

git diff master~1 master -- path/to/file

  • view diffferences between current commit and the previous commit for specific file in diffstat form.
  • It is not mandatory to use path-to-file feature. By default it will show diff between all files

git diff --stat master~1 master -- path/to/file

  • we can also use --word-diff format in native git diff command which is described above in the log section

git diff --word-diff master~1 master -- path/to/file

References

  • References are way of adressing commits. Basic way is to use first 7 letters of SHA-1 hash you get in git log.
  • There are human friendly ways of adressing git too. The two most common are branch name and HEAD keyword.
    • branch name will point to end commit of that branch
    • HEAD keyword will point to the end commit of the current branch in use
  • These references can be used in conjuction with modifiers that make referencing commits somewhat easy but nothing beats the utility of using SHA-1 hash.
  • Following written every command does the same job. Its the matter of preferences:

git diff master~1 master

git diff master~1..master

git diff master~1..

git diff master^ master

git diff master~1 HEAD

git diff 6576b68 6b437c7

  • We can always use command rev-parse to convert reference to SHA-1 hash

git rev-parse master

File System Changes

  • git stores our tracked file in itw own file system and needs to be notified about new file addition, deletion or renaming so that it could also enable or disable tracking for those files. (renaming is simply deletion of current file and moving its content to a new named file).

git mv <filename>

git add -N <filename>

git rm <filename>

Resetting

  • Resetting implies reset the content of the files of repository to some commit in history. Default usage is mentioned below:

git reset --option <target>

  • Resetting contents of the current repo(staged and unstaged) to the last commit requires --hard flag as shown below.

git reset --hard

  • Resetting contents of the tracked files(just the files in staging area) to last commit requires --mixed flag which is the default flag and doesn't requires any flag implicitly.

Working with Remotes

  • There are two ways in which we can have remotes in our repository.
    1. Automatic remote appearances while cloning repos. (written later)
    2. Manual addition and management of remotes.

Manual management of remotes

Add a remote

git remote add <name> <url>

git remote add origin https://www.github.com/gauravgrover95/funky_repo.git

Viewing remotes added
  • checking just the names

git remote OR git remote show

  • checking names with the URL addresses.

git remote -v OR git remote --verbose

Renaming remote

git remote rename <old_name> <new_name>

git remote rename origin nasty_remote

Removing remote

git remote remove <name>

git remove remove nasty_remote

Pushing changes to remote

  • while pushing we can set default branch.<name>.merge setting for current branch.
  • This branch is called tracking branch. it becomes the default location for push or pull(fetch).
  • This setting addresses git from where to pull the changes in future by default

git push --set-upstream <remote_name> <local_branch_name>

git push --set-upstream origin master

git push -u origin master

  • git also supports a --all flag that lets us push all the branches at once

git push --all

  • git also supports --force flag. That skips several checks done by git and is never recommended.

git push --force

Cloning

  • Cloning some remotely hosted open repository to your local system with all the commit history.
  • Cloning is known as checkout in some VCS such as subversion because they have centralized hosted single repo.

git clone <url>

git clone https://github.com/gauravgrover95/crazy_repo.git

-> Shallow Clones: git clone can take a --depth flag that reduces the number of revisions to clone to reduce cloning time for large repos.

Pulling Changes

  • git pull is equivalent to git fetch && git merge. it fetches all the updates.
  • We don't need to mention the branch and the remote if we have pushed once from the repo with -u / --set-upstream flag or we have cloned the repo.

git pull origin master

git pull

Fetching changes

  • Git fetch fetched the changes to the local repository.
  • What this actually means is that it download all the commits and the new or changed files and save it in the branch under remote_branch(say origin_master) and doesn't touch the original local branch(say master).
  • This fetching can be clearly vifsualized using a GUI software such as gitx or gitk.
  • fit fetch can run with 0 or more arguments. fetch without arguments will fetch the default fixed remote/branch via setting up-stream when doing push or when cloned a repo.
  • git fetch can have two arguments: remote_name and branch_name. If only remote_name is passed, that means fetch commits from all the branches.

git fetch

git fetch origin

git fetch origin master

  • for merging the changes. We can use pull command

git pull

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment