Skip to content

Latest commit

 

History

History
327 lines (231 loc) · 14.1 KB

File metadata and controls

327 lines (231 loc) · 14.1 KB

Git

Git is an open source version control tool that enables one to easily track changes and coordinate project works. Git supports non-linear development allowing multiple sections of the project to be amended at the same time. Git works on commandline and it can be used with local or remote repositories. Github is one of popular Git repository server service.

Table of Contents

Structure

Git consists of 3 areas.

Working Tree

Working Tree contains the files that are being worked on. This area is also known as Untracked area and any changes made to the files will be marked yet will not be tracked nor saved by Git. In order to let Git to track the changes, the files must be added to be Staging Area.

Staging Area

Staging Area is where Git starts to track changes made to the files. Yet, any additional changes made to the files after adding them to Staging Area will require one to re-add the files to Staging Area to let Git to save the new changes. In this area, the tracked changes of the files can be committed to Repository.
Note that only files that have been added to Staging Area or been committed will be tracked by Git.

Repository

Repository is where all committed files and their tracked changes are stored.

Installation

Git can be downloaded from its official website.
Git Download

Git bash will be used for any examples below.

Configuration

Current User Setup

This configuration enables identification of any changes made by the user.

$ git config --global user.name "Your name"
$ git config --global user.email "Your email"

*There are 3 levels in configuration:

  • System: on all users
  • Global: on current user for all repositories
  • Currnet: on current repository

Default Editor Setup

Default editor can be defined as below.

$ git config --global core.editor "code --wait"

*code refers to Visual Studio Code *--wait makes the git bash to wait while the editor is open

Files can be opened using the editor.

$ git config --global -e

End of Line Setup

Windows OS and Mac OS mark the end of line differently.

On Windows, the end of line is marked with carriage return & line feed: \r & \n
Whereas on Mac, the end of line is marked with only line feed: \n

This difference can be handled by Git by setting autocrlf.

$ git config --global core.autocrlf true

*On Mac, input is used instead of true

Initialising

To create a new repository, Git must be initialised in the working directory.

$ git init

Staging Files

Files can be added to Staging Area to let Git to track the changes made.

$ git add "File 1" "File 2" -> Specific files can be added together.
$ git add . -> Adds all files in the working directory.
$ git add *.txt -> Adds all .txt files.
$ git reset "file 1" "File 2" -> To unstage files

Check Staging Files

Files on the staging area can be viewed using.

$ git ls-files

Removing File from Staging Area & Working Directory

Files that are committed can be removed from the staging area and working direcotry.
Note that the file in either working directory or staging area must be identical to the committed version.

$ git rm <file name>

Checking Git Status

Status shows files that are currently untracked (Working Tree) and tracked (Staging Area).

$ git status
$ git status -s -> gives shortened status 

Making Commits

Tracked files in Staging Area can be committed with the following command.

$ git commit -m "Commit message"

To edit the message on the editor, run the follow.

$ git commit

*First line is for short description < 80 characters. And long description can be made after a line spacing.

Commit Practice

  • Commit often and make each commit logical and meaningful with comments
  • For commenting, stick to Present tense or Past tense

Commit History

Recent commit history can be checked. And each history log will have commit hash.

$ git log
$ git log --online -> to show each history in one line
$ git log --online --reverse -> from beggining till end

Textual difference of the commit log can be viewed by:

$ git show <commit hash>

And file tree at that commit can be viewed by:

$ git ls-tree <commit hash> 

* This will show file has, and you can 'git show <file hash>' to view the content at that commit snapshot.

Rollback/Revert to specific commit history

This code will rollback to the stage where the specified commit was just made.

$ git revert --no-commit <commit hash ex)0766c053>..HEAD
$ git commit 

The above commands will however still keep the old commit histories.

To rollback while completely remove all history, use the following command.

$ git rebase -i <commit hash> 

-i allows a user to pick commits to drop or amend.

Checking Difference

In addition to Git status, the following code shows all changes made to the files.

$ git diff -> Comparison between working directory & staging area
$ git diff --staged -> Comparison between staging area & repostitory

Visually Checking Changes

Visual diff tool can be used. In this case, VS code will be used.

Firstly, it needs to be defined in the config file.

$ git config --global diff.tool vscode -> defining diff tool's name
$ git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE" -> defining how diff tool, vscode can be launched

*--diff $LOCAL $REMOTE is for comparison with placeholder variables * Run 'git config --global -e' to ensure the config setting is set correctly.

Restore Staged File or Committed File

$ git restore <file name> -> gets a copy of the file in the staging area and overwrite on the file in the working direcotry (restore from staging area)
$ git restore --staged <file name> -> gets a copy of the file in the repository and overwrite on the file in the staging area (restore from repository)

Restore File from Commit Logs

A file can be restored from the commit versions.

1. $ git log --oneline -> to look for committed version of interest
2. $ git ls-tree <commit hash> -> to check if the file is in the commit version
3. $ git restore --source=<commit hash> <file name> -> to restore the file from the specified commit version

Restore Working Tree (Switching Branch)

Files in Working Tree can be restored to the version previously committed. This will create a new branch.
On the other hand, branch can be directly given to change the files in Working Tree.

$ git checkout <Commit hash> -> When restoring to previously committed version. Commit hash can be checked in Git log.
$ git checkout <Branch name> -> When switching to other branch.
$ git checkout master -> To go back to the main branch.
$ git branch -> Shows available branches.

Creating Branch

Branch is an individual environment separeted from the main branch. Branches can coexist at the same time. Bracnhes are often used as a platform to edit codes or experiment features before merging the changes to the main branch.
When changes are committed while on a branch, the committed changes do not affect other branches.

$ git branch <Branch name>

Merging Branches

Branches can be merged by implementing code changed of another branch to the current branch.

$ git merge <Branch name>

Merge Conflict

When changes are made at the same section of the code from both branches, merge conflict occurs. In this case, Git can accept current change, incoming change, both changes or abort merge.
It is recommended to make frequent small commits to avoid conflicts or minimise conflicting area.

Deleting Branch

Branch can be deleted by using the following command.

$ git branch -d <Branch name>

Stashing Files

Files and changes that are not ready to be committed can be stashed (saved temporarily) in local Git repository. This enables one to work on different branches and come back to the stashed work.

$ git stash -> Stashes tracked changes (for files that have been added to Staging Area)
$ git stash -u -> Stashes all files (for files in both Working Tree and Staging Area)
$ git stash pop -> Load stashed files and changes

Ignore Files

Files can be explicitly ignore by Git. These files can be dependency caches or personal IDE config files.

$ touch .gitignore -> create .gitignore file
$ code .gitignore -> edit file using VS code

*File names or patterns can be added on each line.

logs/
main.log
*.log

Remote Repository

There 2 ways that a remote repository can be accessed from local machine.

  • Cloning a remote repository to create a local repository

    $ git clone <directory(optional)>
    This command will download the files from the remote repository and create a local repository. By default the remote repository will become the origin remote repository that you can push to.

    $ git clone -brand <branch_name> <directory(options)>
    This command will download the specific branch of the remote repository.

  • Connecting an existing local repository to a remote repository

    $ git remote add This command adds the remote repository with the specified name. Multiple remote repositories can be set and only one will become the main remote repository.

    $ git remote -v
    This command displays all available remote repositories with the URL.

    $ git remote rm
    $ git remote rename <new_name>
    These commands can be used to amend remote repositories.

Git takes in both HTTP(Hyper Text Transfer Protocol) URL and SSH(Secure Shell) URL for connecting to remote repository.
HTTP allows annoymous access to the remote repository, however, often it is not permitted to push annoymously.
SSH provides authentication and allows more sure way of connecting to the remote repository.

Updating Local Repository

There are 2 ways to update the local repository.

  • Fetch remote repository, view changes and merge
    Fetch will download the commits and files, but will store them as reference withouth impacting the local repository.

    $ git fetch <remote_repository_name> <remote_branch(optional)>
    This command will fetch the all branches (unless specified) of the remote repository.

    $ git branch -r
    This command will display all references for the remote branches that are fetched.

    $ git checkout <fetched_remote_branch>
    This will lead to a detached HEAD state (meaning the current branch is separate from the existing local branch) and changes made in this fetched remote branch will not affect the existing local branch.
    If a local branch is to be created based on this fetched remote branch, the following command can be used.
    $ git checkout -b <now_loca_fetched_remote_branch>

    $ git log <local_branch>..<fetched_remote_branch> --oneline
    This command will display all the commits made in the upstream branch.

    When merge is to be made, point to the local branch to be merged, and merge with the fetched remote branch.
    $ git checkout <local_branch>
    $ git merge <fetched_remote_branch>
    Note that when these two branches have no common base, an error will occur: "refusing to merge unrelated histories"
    This can be resolved by using the following parameter.
    $ git merge <fetched_remote_branch> --allow-unrelated-histories

  • Pull remote repository while merging all contents automatically
    Git pull is combination of git fetch and git merge. This is considered unsafe way that can put the current branch into a conflicted state. So careful execution is required.

    $ git pull <remote_repository>
    This command is equivalent to the following commands:
    $ git fetch <remote_repository> HEAD & $git merge HEAD
    HEAD referrs to the current branch.

Pushing to Remote Repository

$ git push <remote_name> <local_branch_name>

This command will push the changes in the local branch to the remote repository. By default when remote_name and local_branch_name are not given the changes made in the current local branch will be pushed to the origin remote repository. This behaviour can be configured.

$ git push <remote_name> <local_branch_name>:<remote_branch_name>

By default, Git will push the changes in the specified local branch to the same remote branch. If you want to push the changes to the other remote repository branch, this command can be used. Also, it's a good idea to push to a new remote repository branch and create a pull request to make changes to the main remote branch while getting the changes checked by peers.